Здравствуйте, _FRED_, Вы писали:
_FR>В такой постановке — да. Тогда, покажи пример класса, описывающего таблицу? Вернее, описывающего строку таблицы.
Ну как то так:
public class TestClass : KeyedObjectBase
{
private string _name;
private string _description;
private int _nonPersistent;
public TestClass(Guid primaryKey) : base(primaryKey)
{
}
[DataMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember]
public string Description
{
get { return _description; }
set { _description = value; }
}
[DataMember(false)]
public int NonPersistent
{
get { return _nonPersistent; }
set { _nonPersistent = value; }
}
}
_FR>Каждое свойство класса, описывающего таблицу, помеченно каким-либо аттрибутом — это "колонка" таблицы. Имеет-ли смысл держать в таком классе другие свойства?
По желанию.
_FR> Какие?
Ну, к примеру те же вычисляемые свойства. Или свойства агрегирующие простые типы в более сложные объекты.
_FR> Может, это и не класс вовсе, а интерфейс\абстрактный класс с декларацией свойств?
Сложный вопрос. Я пока не могу дать на него однозначного ответа.
_FR>Имеет ли смысл строить иерархию таких классов\интерфейсов для обозначения таблиц со схожей структурой?
Имеет. Весь вопрос как эту иерархию в итоге отображать на В-деревья в файле. Я лично знаю 3 способа.
Здравствуйте, Cyberax, Вы писали:
>> Ну и? Что я должен был увидеть? C>Прикладной код (редактирование и т.п.) отделен от логики транзакций. C>Например, мы можем без всякого изменения кода отредактировать пачку из C>10 писем, а потом разом сохранить.
Я тебя про другое спрашивал — зачем отдельно иметь транзакции в БД, отдельно их обертки в прикладном коде.
Здравствуйте, eao197, Вы писали:
E>>>Ну а как назвать то, что ты будешь в своей БД хранить?
AVK>>Данные.
E>Ну вот считай, что твои данные я называю объектом.
Все сразу?
AVK>>Я же тебе объяснил — перезапись страницы значительно дешевле чем правка ссылок в нескольких страницах. Что же касается отдельной таблицы пересчета адресов то это пустой расход памяти и диска, раздувание файла БД, лишняя косвенность и еще одна возможность для сбоев.
E>Ты не понял полностью. Нет перезаписи страницы.
Вот и плохо что нет. Пойми простую вещь — на диск все равно меньше 512 байти не запишешь, даже если тебе всего 8 байт ссылки надо поправить. Соответственно править ссылки в 3 страницах будет медленнее, нежели перезаписать содержимое одной единственной. А таблица пересчета, спасая от правки ссылок в страницах, привносит свои проблемы.
E>А таблица пересчета адресов -- это очень быстро.
Тем не менее медленнее чем без нее.
E> И достаточно компактно.
Пусть страница 8К. Размер БД 10Г. Итого размер таблицы пересчета = 10Г / 8К * 16 = 20М. Считаешь 20 мег это немного?
E> Да и лишних возможностей для сбоев я не вижу.
Плохо смотришь. Сбой в таблице пересчета абсолютно критичен. Следовательно, внося эту таблицу, мы снижаем надежность системы в целом на вероятность сбоя в таблице пересчета.
И обмены с БД идут объектами trx_info_t. Вот trx_info_t я и называю объектом.
E>>Ты не понял полностью. Нет перезаписи страницы.
AVK>Вот и плохо что нет. Пойми простую вещь — на диск все равно меньше 512 байти не запишешь, даже если тебе всего 8 байт ссылки надо поправить. Соответственно править ссылки в 3 страницах будет медленнее, нежели перезаписать содержимое одной единственной. А таблица пересчета, спасая от правки ссылок в страницах, привносит свои проблемы.
Это я понимаю. Но таблица пересчета кроме проблем дает и преимущества. Например, с ее помощью избавляешься от проблемы фрагментации БД.
AVK>Тем не менее медленнее чем без нее.
Ну это не серьезно, право слово.
Обращение:
a[i]
конечно же медленне, чем
a[ t[i] ]
но по сравнению со скоростями дисковой подсистемы...
E>> И достаточно компактно.
AVK>Пусть страница 8К. Размер БД 10Г. Итого размер таблицы пересчета = 10Г / 8К * 16 = 20М. Считаешь 20 мег это немного?
Почему на 16 умножается? Страница 8K -- это 2^13 байт. Если номер страницы будет 4-х байтовый (т.е. использовать в качестве адресации не смещения странц, а их порядковые номера), то всего объем БД может составлять 2^32 * 2^13 = 2^45 = 32Tb.
Значит для 16Gb БД потребуется 2^22 страниц. Для таблицы пересчета потребуется 2^24 = 8M. Если я не ошибся в подсчетах.
И это при том, что всю таблицу пересчета в ОП можно не хранить, а подгружать сегменами по мере надобности. С учетом фактора локальности ссылок это не должно быть большой проблемой.
Но здесь следовало бы поэкспериментировать на прототипах с замерами производительности.
AVK>Плохо смотришь. Сбой в таблице пересчета абсолютно критичен. Следовательно, внося эту таблицу, мы снижаем надежность системы в целом на вероятность сбоя в таблице пересчета.
Надежность фиксации таблицы пересчета конечно же важна. Но подумай сам, неужели надежность фиксации WAL должна быть ниже? Представь, что ты записал WAL, после чего начал коммитить страницы в основной файл БД. Произошел сбой и БД пришлось восстанавливать путем доката WAL. Но если что-то в WAL запортилось, и ты этого не смог обнаружить, то бяка все равно случится. Механизм фиксации транзакций должен быть по-определению надежным. В меру возможности.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, GlebZ, Вы писали:
AVK>>Тока с сабжем это немного общего имеет. GZ>Ну вот. Ограничиваем применимость сабжа?
Да, конечно. Невозможно сождать эффективную, простую и универсальную БД одновременно.
AVK>>Вот за смысл я как раз и цепляюсь. Ты постоянно пытаешься трактовать LINQ как еще один текстовый язык запросов, а это совсем не так. GZ>Возьми espresso, и у тебя есть тектовой язык запросов.
А нафига его брать? Ты пойми — мне не интересны все эти сетафизические предположения, меня интересует практический аспект. А в этом случае LINQ это прежде всего набор фич языка, и декларативные запросы там далеко не самая важная их часть. Если бы их не было вовсе ничего бы принципиально не изменилось, функциональная форма совсем не хуже.
GZ> Немного лучше HQL и немного хуже XQuery. Смысл то у них, одинаковый.
Смысл у них разный.
Вобщем вот определение:
We use the term language integrated query to indicate that query is an integrated feature of the developer’s primary programming languages (e.g., C#, Visual Basic). Language integrated query allows query expressions to benefit from the rich metadata, compile-time syntax checking, static typing and IntelliSense that was previously available only to imperative code. Language integrated query also allows a single general purpose declarative query facility to be applied to all in-memory information, not just information from external sources.
Читайте доки, они рулез.
GZ>Зачем keyset? Зачем курсоры? Мы можем дать пользователю единую феню и не мучить его не особо нужным функционалом.
Затем что причины, почему ООБД до сих пор не получили распространения всем хорошо известны.
Здравствуйте, Sinclair, Вы писали:
AVK>>2) Что лучше — выборки или навигационный способ(курсоры). S>Лучше, наверное, все же выборки. Они позволяют лучше масштабировать производительность: при изменении статистики декларативный движок может сменить план запроса.
Тут только надо помнить насколько это реализуемона практике.
AVK>>3) Что лучше — декларативный sql-like синтаксис или функциональный стиль? S>А можно попонятнее?
А что конкретно непонятно?
AVK>>2) Допустим ли (и возможен ли?) полный отказ от нетипизированных данных (нетипизированных на уровне строки) при работе с БД? S>Имеется в виду отказ от byte[]?
Имеется ввиду произвольный формат строки без наличия соответствующего кортежа, описанного в терминах CLR.
S> Нет, недопустим.
Здравствуйте, Sinclair, Вы писали:
S>Речь о том, что все таки нужен вменяемый оптимизатор. В одной руке у него логический план, сформированный именно в виде лямбд. В другой руке — статистика базы (примитивная статистика есть всегда, как минимум в виде Unique и FK Constraints). На выходе именно он должен выдавать план запроса.
Оптимизатор это уже после, когда более менее ясно что требуется. Вопрос в другом — как на основании запроса понять, что физически нужно делать те или иные операции?
AVK>>2) Введение двух форм методов — один с лямбдой, другой с параметрами, описывающими работу с индексом. S>Вторая форма является аналогом хинтов SQL серверов.
Нет. Вторая форма является аналогом SQL. Когда парсер фактически дает описание что выбирать. А хинты отрабатываются уже потом.
S>В полной реляционной модели самые проблемные — это джойны/проекции и группировка. S>Агрегатные запросы мало того, что имеют тенденцию плохо оптимизироваться, они еще и усложняют type inference.
При наличии курсоров агрегаты можно считать в памяти примитивным кодом. А вот выборки все делают намного печальнее, потому что далеко не факт, что выборка влезет в доступную память.
S>Навигационный подход удобен тем, что он никогда не возвращает никаких туплов, не описанных явно в метаданных.
Вот именно.
S>Мораль в том, что надо понять, чего собственно хочется — либо полная реляционная модель (вместе со всеми экзотическими фичами типа non-equality join, джойнов с вычисляемыми полями, агрегатов с окном и прочей экзотикой), либо ограниченная модель, в которой удобно и быстро выполняются некоторые основные операции.
Здравствуйте, GlebZ, Вы писали:
GZ>У меня сейчас как раз такие фантазеры и наваяли большую, в общем, чудо. Большой набор больших механизмов без всякого понятия а для чего ж они нужны вообще всей предметной задаче. Так что у меня на такие слова нервный тик. GZ>Попробуй привести несколько примеров где данная БД может быть использована.
Я пример уже приводил — почтовый клиент.
AVK>>А зачем для кеша какая то особенная БД? GZ>Минимум она должна держать идентификацию совместимую с основным сервером идентификацию.
Здравствуйте, Serginio1, Вы писали:
S> Ничто не мешает сделать многопользовательский доступ, но на уровнем удаленных методов. В большинстве случаев этого достаточно.
Знаешь, я на эту тему с тобой спорить не буду, потому как бесполезно. Можешь делать. Когда сделаешь, тогда и поговорим. А пока что мой опыт свидетельствует, что твои слова далеки от реальности.
AVK>>Т.е. данные внутри БД описываются системой типов самой БД, а прикладной код должен самостоятельно выполнять конверсию? И что мы выигрываем при этом?
S> ООП подход.
??? Это конверсия типов то ООП?
S> БД нужно только знание IComparer для индексов и длина записи. В большинстве случаев поля будут иметь неопределенный тип итд.
Ерунда. Поле в БД не может иметь неопределенный тип, хотя бы потому что на тип завязано построение В+ дерева.
S> Я смотрю на такую БД с точки зреня 1С, Паруса , акзапты.
Рекомендую почитать в SQL BOL про организацию файлов MDF. Там все довольно внятно расписано. Не думаю, что стоит изобретать какой-то более хитрый велосипед; разве что покрутить стратегии компактификации БД. В остальном изменения в Yukon сделаны в нужную сторону. К примеру, varchar(max) и varbinary(max) — это просто the must для этой потенциальной встраиваемой БД. Потому что не стоит парить разработчика выбором длины поля типа string и вопросами перехода на Memo. Должны храниться просто System.String, и работать соответственно — быстро для коротких строк, помедленнее для больших. Вот и все чудеса в решете. А то каждый раз думать, сколько места отводить под имя/фамиилию, приклеивать валидаторы к UI...
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, eao197, Вы писали:
AVK>>Все сразу?
E>Блин, Андрей... Чего-то ты к словам цепляешься.
Я не к словам цепляюсь. Просто ты начинаешь говорить о чем то, о чем я даже не спрашивал. Еще раз — я понятия не имею о чем ты сейчас думаешь, поэтоиу додумывать за тебя не имею возможности. Я в исходном вопросе ни о каких объектах не говорил, я вобще предполагал что БД будет все таки реляционной.
E> Ты можешь сам сказать-то что и как ты хочешь записывать в БД и считывать из БД?
Неконкретный вопрос, на который можно дать только неконкретный ответ: хочу записывать и считывать персистентные пользовательские данные.
E>И обмены с БД идут объектами trx_info_t. Вот trx_info_t я и называю объектом.
Есть как минимум 2 варианта того, что может быть объектом
1) Базовый набор атрибутов, образующих кластерный индекс в файле БД
2) Кортеж, состав атрибутов которого описан в запросе.
Ты о каком из них? Неужели так сложно отойти от заезженой схемы O/R мепперов и взглянуть на ситуацию хоть немножечко пошире?
AVK>>Вот и плохо что нет. Пойми простую вещь — на диск все равно меньше 512 байти не запишешь, даже если тебе всего 8 байт ссылки надо поправить. Соответственно править ссылки в 3 страницах будет медленнее, нежели перезаписать содержимое одной единственной. А таблица пересчета, спасая от правки ссылок в страницах, привносит свои проблемы.
E>Это я понимаю. Но таблица пересчета кроме проблем дает и преимущества. Например, с ее помощью избавляешься от проблемы фрагментации БД.
Не избавляюсь, а лишь замазываю проблему. Я могу убрать фрагментацию логическую (что, вобщем то, не особенно и нужно, потому что 64 бит хватит выше крыши), а вот физическую фрагментацию я так не исправлю.
E>но по сравнению со скоростями дисковой подсистемы...
Ты еще не забыл, что твою таблицу надо грузить целиком в память, а при коммите транзакции немедленно скидывать изменившуюся часть на диск?
AVK>>Пусть страница 8К. Размер БД 10Г. Итого размер таблицы пересчета = 10Г / 8К * 16 = 20М. Считаешь 20 мег это немного?
E>Почему на 16 умножается?
Потому что размер записи таблицы 16 байт — 8 байт логический номер и 8 байт физический адрес. Но даже если брать по 4 байта, все равно 10М это весьма и весьма немало.
E>И это при том, что всю таблицу пересчета в ОП можно не хранить, а подгружать сегменами по мере надобности.
И тут мы попадаем на лишнее обращение к диску (причем с длинным сиком) с катастрофическим падением производительности.
AVK>>Плохо смотришь. Сбой в таблице пересчета абсолютно критичен. Следовательно, внося эту таблицу, мы снижаем надежность системы в целом на вероятность сбоя в таблице пересчета.
E>Надежность фиксации таблицы пересчета конечно же важна. Но подумай сам, неужели надежность фиксации WAL должна быть ниже?
Там структуры проще и примитивнее и запись последовательная. Опять же сбой в WAL всего лишь приведет к неоткату транзакции (или неверному откату). Неприятно, но не смертельно. Главное, что физическая структура БД не испортится. А вот сбой в таблице пересчета это уже капец всей базе.
Здравствуйте, Sinclair, Вы писали:
S>Рекомендую почитать в SQL BOL про организацию файлов MDF. Там все довольно внятно расписано. Не думаю, что стоит изобретать какой-то более хитрый велосипед; разве что покрутить стратегии компактификации БД. В остальном изменения в Yukon сделаны в нужную сторону. К примеру, varchar(max) и varbinary(max) — это просто the must для этой потенциальной встраиваемой БД. Потому что не стоит парить разработчика выбором длины поля типа string и вопросами перехода на Memo. Должны храниться просто System.String, и работать соответственно — быстро для коротких строк, помедленнее для больших. Вот и все чудеса в решете. А то каждый раз думать, сколько места отводить под имя/фамиилию, приклеивать валидаторы к UI...
Интересно, а каким боком все это относится к моему сообщению?
К слову, моя система хранения как раз и создавалась для того, чтобы хранить объекты, динамически изменяющие свой размер (вроде std::string, std::vector, std::list и пр.).
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали:
AVK>Есть как минимум 2 варианта того, что может быть объектом AVK>1) Базовый набор атрибутов, образующих кластерный индекс в файле БД AVK>2) Кортеж, состав атрибутов которого описан в запросе.
Стало быть я говорю о кортеже.
AVK>Неужели так сложно отойти от заезженой схемы O/R мепперов и взглянуть на ситуацию хоть немножечко пошире?
Ты будешь смеяться, но я только один раз работал с O/R мапперами (в RubyOnRails). А все остальное время с точки зрения разработчика очень примитивной ООБД
AVK>Не избавляюсь, а лишь замазываю проблему. Я могу убрать фрагментацию логическую (что, вобщем то, не особенно и нужно, потому что 64 бит хватит выше крыши), а вот физическую фрагментацию я так не исправлю.
Исправишь. Представь, что во время сохранения в БД твой кортеж оказался размазанным по нескольким разрозненным страницам хранилища. Все. Если ты его будешь обновлять только по этому месту, то он у тебя навсегда останется фрагментированным. Если при каждом обновлении ты будешь его перезаписывать в новое место, есть вероятность (имхо, большая), что ты сможещь записывать его последовательно.
AVK>Ты еще не забыл, что твою таблицу надо грузить целиком в память, а при коммите транзакции немедленно скидывать изменившуюся часть на диск?
Я думаю, что не нужно. Таблица может точно так же помещаться в кэш и выбрасываться оттуда при не надобности.
E>>И это при том, что всю таблицу пересчета в ОП можно не хранить, а подгружать сегменами по мере надобности.
AVK>И тут мы попадаем на лишнее обращение к диску (причем с длинным сиком) с катастрофическим падением производительности.
Здесь лучше бы опираться на реальные замеры.
E>>Надежность фиксации таблицы пересчета конечно же важна. Но подумай сам, неужели надежность фиксации WAL должна быть ниже?
AVK>Там структуры проще и примитивнее и запись последовательная. Опять же сбой в WAL всего лишь приведет к неоткату транзакции (или неверному откату).
Я говорил о другом. Если ты записал в WAL успешно, выполнил fsync, начал запись в БД. Произошел жесткий сбой. Файл WAL запортился. БД уже была частично изменена. Все, приплыли.
AVK> Неприятно, но не смертельно. Главное, что физическая структура БД не испортится. А вот сбой в таблице пересчета это уже капец всей базе.
Для этого можно использовать две копии таблицы (я об этом уже говорил).
И обновлять можно не всю таблицу в конце транзакции, а только изменившиеся ее части.
Собственно, выбирать-то тебе. Я просто хотел сказать, что такой механизм фиксации транзакций так же возможен.
В моей БД WAL дает очень сильный оверхэд при фиксации транзакций. Я бы хотел от него избавиться, вот только попробовать использовать shadow copy пока нет времени.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Sinclair, Вы писали:
S>Рекомендую почитать в SQL BOL про организацию файлов MDF.
А там это описано?
S>К примеру, varchar(max) и varbinary(max) — это просто the must для этой потенциальной встраиваемой БД. Потому что не стоит парить разработчика выбором длины поля типа string и вопросами перехода на Memo.
Здравствуйте, eao197, Вы писали:
E>Стало быть я говорю о кортеже.
Но тогда о каких ссылках на кортежи может идти речь, если сам кортеж может состоять из данных, размещенных в разных индексах? Например такое происходит если кортеж получен в результате джойна.
AVK>>Неужели так сложно отойти от заезженой схемы O/R мепперов и взглянуть на ситуацию хоть немножечко пошире?
E> E>Ты будешь смеяться, но я только один раз работал с O/R мапперами (в RubyOnRails). А все остальное время с точки зрения разработчика очень примитивной ООБД
Не суть важно. Главное что схема одна и та же. Но она далеко не единственно возможная.
E>Исправишь. Представь, что во время сохранения в БД твой кортеж оказался размазанным по нескольким разрозненным страницам хранилища. Все. Если ты его будешь обновлять только по этому месту, то он у тебя навсегда останется фрагментированным.
Непонимаю. Какой кортеж? Кортеж образуется только на этапе запроса. Это read-only структура. Его нельзя менять.
AVK>>Ты еще не забыл, что твою таблицу надо грузить целиком в память, а при коммите транзакции немедленно скидывать изменившуюся часть на диск?
E>Я думаю, что не нужно.
Нужно в обязательном порядке, иначе вылет приложения порушит БД.
E> Таблица может точно так же помещаться в кэш и выбрасываться оттуда при не надобности.
Писать надо сразу, иначе проблем будет слишком много. И непонятно зачем тогда транзакции, если даже после коммита их содержимое может быть потеряно.
E>Я говорил о другом. Если ты записал в WAL успешно, выполнил fsync, начал запись в БД. Произошел жесткий сбой. Файл WAL запортился. БД уже была частично изменена. Все, приплыли.
И я об этом. Не приплыли, потому что физическая структура повреждена не будет, повредится только логическая структура, если в транзакции были согласованные изменения. Это значительно менее страшно.
E>Для этого можно использовать две копии таблицы (я об этом уже говорил).
Это называется положить грабли, а потом строить сверху мост.
E>Собственно, выбирать-то тебе.
Ну почему обязательно мне . Я пока что обсуждаю что тут вобще можно сделать существенно лучше, чем существующие решения. Правда, если когда нибудь дело дойдет до реализации, вряд ли тебе будет интересна реализация под .NET.
E> Я просто хотел сказать, что такой механизм фиксации транзакций так же возможен.
Иван тебе уже объяснил, почему смысла в нем особого нет. Если уж отказываться от WAL, то я бы подумал в сторону Redo Only лога.
Здравствуйте, AndrewVK, Вы писали:
AVK>Но тогда о каких ссылках на кортежи может идти речь, если сам кортеж может состоять из данных, размещенных в разных индексах? Например такое происходит если кортеж получен в результате джойна.
Про ссылки на кортежи я не говорил. Я говорил про ссылки между страницами B+ дерева в индексе. Их можно было бы делать через лишний уровень косвенности. Ну да эту тему мы уже обсудили, судя по всему
E>>Исправишь. Представь, что во время сохранения в БД твой кортеж оказался размазанным по нескольким разрозненным страницам хранилища. Все. Если ты его будешь обновлять только по этому месту, то он у тебя навсегда останется фрагментированным.
AVK>Непонимаю. Какой кортеж? Кортеж образуется только на этапе запроса. Это read-only структура. Его нельзя менять.
Но ведь кортеж из чего-то будет подниматься. Значит прежде select-а, ты должен будешь сделать insert. В insert-е же у тебя все равно будет какой-то кортеж. Не факт, что он у тебя будет в одну страницу помещаться (особенно с учетом varchar переменного размера).
AVK>>>Ты еще не забыл, что твою таблицу надо грузить целиком в память, а при коммите транзакции немедленно скидывать изменившуюся часть на диск?
E>>Я думаю, что не нужно.
AVK>Нужно в обязательном порядке, иначе вылет приложения порушит БД.
Я говорил о том, что не нужно всю таблицу в память загружать.
AVK>И я об этом. Не приплыли, потому что физическая структура повреждена не будет, повредится только логическая структура, если в транзакции были согласованные изменения. Это значительно менее страшно.
Не понимаю. На странице у тебя будет управляющая информация обязательно. Какие-то метки полей, размерности и пр. Если они запортятся, то считай, что и физическая структура баз полетит.
E>> Я просто хотел сказать, что такой механизм фиксации транзакций так же возможен.
AVK>Иван тебе уже объяснил, почему смысла в нем особого нет. Если уж отказываться от WAL, то я бы подумал в сторону Redo Only лога.
Ну здесь есть разные мнения. Константин Книжник не зря в своих БД shadow copy использует. А он очень обстоятельно, насколько я заметил, к разработке подходит.
А Redo Only лог позволит транзакции откатывать?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, AndrewVK, Вы писали: AVK>Тут только надо помнить насколько это реализуемона практике.
Прекрасно реализуемо. Примеров тому довольно много AVK>>>3) Что лучше — декларативный sql-like синтаксис или функциональный стиль? S>>А можно попонятнее?
AVK>А что конкретно непонятно?
Что такое декларативный sql-like синтаксис я понимаю. А вот что такое "функциональный стиль" — не очень. Ты имеешь в виду линqовские лямбды/анонимные методы? AVK>>>2) Допустим ли (и возможен ли?) полный отказ от нетипизированных данных (нетипизированных на уровне строки) при работе с БД? S>>Имеется в виду отказ от byte[]?
AVK>Имеется ввиду произвольный формат строки без наличия соответствующего кортежа, описанного в терминах CLR.
А, вот это как раз возможно и допустимо. Проекции можно делать и игнорированием лишних полей (т.к. у нас нет узкого места — сети для перекачки лишнего трафика между клиентом и сервером); джойны, наверное, можно делать и в виде доп.навигации (коли захочется). В общем, не уверен. AVK>Почему?
Это я про byte[]. Просто потому, что есть масса данных, которые иначе как в виде byte[] особо и не представишь. К тому же если есть охота хранить всякие пользовательские типы, то это 100% будет сделано через сериализацию и именно в byte[] переменной длины, т.к. в фиксировнную байт-раскладку умеют превращаться только структы.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Sinclair, Вы писали:
S>>Рекомендую почитать в SQL BOL про организацию файлов MDF.
AVK>А там это описано? здесь
S>>К примеру, varchar(max) и varbinary(max) — это просто the must для этой потенциальной встраиваемой БД. Потому что не стоит парить разработчика выбором длины поля типа string и вопросами перехода на Memo.
AVK>+1000!
Только это сильно усложнит систему хранения и операций с ним. Да и статистику, если будешь делать, также.
Здравствуйте, GlebZ, Вы писали:
AVK>>+1000! GZ>Только это сильно усложнит систему хранения и операций с ним. Да и статистику, если будешь делать, также.
Здравствуйте, eao197, Вы писали:
AVK>>Непонимаю. Какой кортеж? Кортеж образуется только на этапе запроса. Это read-only структура. Его нельзя менять.
E>Но ведь кортеж из чего-то будет подниматься. Значит прежде select-а, ты должен будешь сделать insert. В insert-е же у тебя все равно будет какой-то кортеж.
Нет, вот в insert я должен использовать то, что я упоминал под п.1.
E> Не факт, что он у тебя будет в одну страницу помещаться (особенно с учетом varchar переменного размера).
В классических БД он обязан помещаться на одну страницу. Даже с учетом varchar. Единственное исключение это varcharmax и varbinarymax в последнем сиквеле.
AVK>>Нужно в обязательном порядке, иначе вылет приложения порушит БД.
E>Я говорил о том, что не нужно всю таблицу в память загружать.
Насчет лишней записи на диск возражений нет?
E>Не понимаю. На странице у тебя будет управляющая информация обязательно. Какие-то метки полей, размерности и пр. Если они запортятся, то считай, что и физическая структура баз полетит.
В логе не пишется изменение физической разметки, в логе пишутся только логические операции. Если в момент записи порушится именно физическая структура БД (в единичном обращении к диску), то вне зависимости от схемы БД придет пипец. Я же говорю о другом — когда просто транзакция не успела закоммититься при сбое, например приложение вылетело на полпути при коммите.