|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
Проектирую некое хранилище данных (для большого количества записей). Есть некие объекты, которых может быть очень много (до 5 миллионов). В этой БД будет содержаться информация для каждого из объектов. Каждый объект идентифицируется по его уникальному глобальному GUID (16 байтов), т.к. таких БД может быть несколько и возможен импорт данных из одной в другую. Так вот изначально проектировали под СУБД (MySQL/MSSQL) и соответсвенно планировани хранить в таблице объектов глобальный GUID и внутренний ID (INT 32 / INT 64). Но сейчаз решили что функций SQLite вполне достаточно. Тип GUID будет представлен как BLOB в 16 байт. И вот у меня появилось 3 возможных решения: 1) оставить в таблице объектов глобальный GUID и внутренний ID (индексы только для ID); 2) использовать в БД только GUID (индексы только по нему); 3) использовать в БД только GUID, но представленнный в виде двух полей типа INTEGER (индекс по обоим полям). Какой вариант оптимальнее для SQLite? И ещё 3 тупых вопроса: Правильно ли я понимаю, что значения полей типа INTEGER в DB-файле будет преставлено в виде ANSI-строк? Правильно ли я понимаю, что значения полей типа BLOB в DB-файле будет преставлено в виде UTF-8 строки? Имеет ли какое то значение тип поля при создании для него индекса? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2012, 18:48 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
metosПроектирую некое хранилище данных (для большого количества записей). Есть некие объекты, которых может быть очень много (до 5 миллионов). В этой БД будет содержаться информация для каждого из объектов. Каждый объект идентифицируется по его уникальному глобальному GUID (16 байтов), т.к. таких БД может быть несколько и возможен импорт данных из одной в другую. Так вот изначально проектировали под СУБД (MySQL/MSSQL) и соответсвенно планировани хранить в таблице объектов глобальный GUID и внутренний ID (INT 32 / INT 64). Но сейчаз решили что функций SQLite вполне достаточно. Тип GUID будет представлен как BLOB в 16 байт. И вот у меня появилось 3 возможных решения: 1) оставить в таблице объектов глобальный GUID и внутренний ID (индексы только для ID); 2) использовать в БД только GUID (индексы только по нему); 3) использовать в БД только GUID, но представленнный в виде двух полей типа INTEGER (индекс по обоим полям). Какой вариант оптимальнее для SQLite? Исходите из отношения таблиц. GUID нужен только для внешней связки при импорте/экспорте и не используется приложением? Тогда лучше вообще храните его в отдельной таблице, а для связки используйте INTEGER PRIMARY KEY - это в SQLite самый оптимальный индекс ( http://sqlite.org/lang_createtable.html#rowid). Только учтите, что PK в SQLite не подразумевает NOT NULL - последний нужно определять явно. metosИ ещё 3 тупых вопроса: Правильно ли я понимаю, что значения полей типа INTEGER в DB-файле будет преставлено в виде ANSI-строк? Правильно ли я понимаю, что значения полей типа BLOB в DB-файле будет преставлено в виде UTF-8 строки? Имеет ли какое то значение тип поля при создании для него индекса? 1. Нет. В SQLite столбцы не типизированные, неявного приведения типов нет: что занесете, то и будет хранить. Хранимые типы описаны в мануале: http://sqlite.org/datatype3.html 2. Нет. См. ссылку выше. 3. Имеет. Индекс как раз типизирован (иначе и быть не могло). Чем короче индекс, тем быстрее поиск. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2012, 19:58 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
RXLИсходите из отношения таблиц. GUID нужен только для внешней связки при импорте/экспорте и не используется приложением? Тогда лучше вообще храните его в отдельной таблице, а для связки используйте INTEGER PRIMARY KEY - это в SQLite самый оптимальный индекс ( http://sqlite.org/lang_createtable.html#rowid). Только учтите, что PK в SQLite не подразумевает NOT NULL - последний нужно определять явно. GUID также используется при работе приложения. Поле ID (32/64 бита) появилось лишь из-за того, что это оптимальный способ для построения индекса. Из-за этого поля появилась доп. таблица, которая связывает ID и GUID. Но ведь можно обойтись и без этой таблицы и поля ID, просто работая сразу с GUID. Но GUID представлен как BLOB(16), для которого индекс вообще не оптимален. Вот я и предложил представить в БД GUID как два поля GUID_LOW и GUID_HIGH (типа INTEGER). Впринципе, в таком варианте индекс будет достаточно "повесить" на только на поле GUID_LOW, что будет эффективно при выборке, да и размер индексов уменьшит. Также придётся добавить один UNIQUE индекс, содержащий оба поля GUID_LOW и GUID_HIGH - для контроля уникальности. Либо самому контролировать уникальность. Что лучше пока не знаю. Идея с двумя полями стоящая? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2012, 22:21 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
Про UNIQUE индекс написал фигню. Как раз таки в случае полей GUID_LOW и GUID_HIGH отпадает необходимость в контроле уникальности GUID, т.к. нету связывающей таблицы со списков всех GUID. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2012, 22:34 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
metos, Если в запросе одна таблица, то адресовать напрямую по GUID будет оптимальнее, чем искать GUID по одной таблице, а потом по другой искать по INTEGER. Если в запросе несколько таблиц и вы их будете связывать по GUID, то однозначно INTEGER лучше. Да и работать с целыми удобнее, чем с BLOB. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2012, 00:56 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
Индекс по GUID будет очень сильно замедлять вставку данных. Стоит проверить на своих объемах. Мои тесты см. здесь: http://geomapx.blogspot.com/search?q=index+degradation Там внизу есть данные по сравнению скорости вставки для randomblob(8), randomblob(16) и проч. Скорость выборки при этом не страдает, потому для селектов тесты и не нужны, кроме особых случаев. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.02.2012, 02:30 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
MBGИндекс по GUID будет очень сильно замедлять вставку данных. Стоит проверить на своих объемах. Мои тесты см. здесь: http://geomapx.blogspot.com/search?q=index+degradation Там внизу есть данные по сравнению скорости вставки для randomblob(8), randomblob(16) и проч. Скорость выборки при этом не страдает, потому для селектов тесты и не нужны, кроме особых случаев. Ясно что индекс по BINARY менее эффективен. Если сделать UNIQUE индекс, объединяющий два поля типа INTEGER, как это отразится на скорости? Как вашу функцию intrange2table представить на Tcl ? Как под виндою, используя MSYS + TclTk, выполнять тесты? (хочется сопоставить скорость sqlite и sqlcipher) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.02.2012, 15:05 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
MBGСкорость выборки при этом не страдает ....... кроме особых случаев. А почему скорость выборки не страдает? В качестве индекса используется 64-битный хэш от BINARY ? Что за особые случаи? (хоть 1 пример) ... |
|||
:
Нравится:
Не нравится:
|
|||
29.02.2012, 15:17 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
metosMBGСкорость выборки при этом не страдает ....... кроме особых случаев. А почему скорость выборки не страдает? В качестве индекса используется 64-битный хэш от BINARY ? Что за особые случаи? (хоть 1 пример) Пример простой - индекс по гигабайтному блобу очевидно намного медленнее, чем по числу типа integer. В случае же разумной длины ключей скорость выборки заметно не изменяется, а вот вставка замедляется заметно, т.к. сжатия индексов в эскулайте нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
29.02.2012, 22:01 |
|
Стоит ли GUID заменить на два INTEGER ?
|
|||
---|---|---|---|
#18+
metosЕсли сделать UNIQUE индекс, объединяющий два поля типа INTEGER, как это отразится на скорости? Скорости чего? На селектах - скорее, всего, никак, разницы не заметить. На вставках - точно медленнее будет, притом в два раза быстрее в кэш упретесь и после того совсем хреново станет, а вообще зависит от распределения данных (предварительно отсортированные значения типа PK вставляются лучше всего - не требуется сильно модифицировать индексное дерево на вставках). metosКак вашу функцию intrange2table представить на Tcl ? Простым циклом заполнить временную табличку нужными значениями. Или вот такой модуль взамен использовать: http://mobigroup.ru/debian/pool-squeeze/main/s/sqlite3-ext-wholenumber/ Под винду я его не тестировал, но должен работать без проблем. metosКак под виндою, используя MSYS + TclTk, выполнять тесты? (хочется сопоставить скорость sqlite и sqlcipher) Странный вопрос: tclsh8.5 filename.tcl ... |
|||
:
Нравится:
Не нравится:
|
|||
29.02.2012, 22:08 |
|
|
start [/forum/topic.php?fid=54&msg=37684534&tid=2009059]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
31ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 133ms |
0 / 0 |