Добрый день. У меня задача сделать уникальный идентификатор записи в бд. Т.е. имеется очень много файлов, в имени файла есть три даты: начало и конец периода и дата создания (но вместе с тем, уникальность имени не гарантирована). Данные из этих файлов загружаются моей программой в таблицу бд. Записей может быть больше 20 млрд.
Идея есть такая. Посчитать crc32 по строке имя файла + размер файла. Затем из четырёх байт crc32 сделать 3, например помножив 0 и 1 байт crc32, эти 3 байта сделать старшими в unsigned long long int моего идентификатора, ну а нижние 5 байтов использовать как место для счетчика порядкового номера записи каждого файла...
Вопрос собственно в том, здраво ли это звучит и как именно установить 3 старший байта и потом инкриминировать 5 нижних отдельно от всех 8 байт...
надеюсь сформулировал понятно...)
Здравствуйте, .alex, Вы писали:
A>Добрый день. У меня задача сделать уникальный идентификатор записи в бд.
Уникальный идентификатор в бд может создавать сама бд.
А если надо привязать к содержимому файла то чем обычные hash-ы не угодили md5,sha1,sha256,...
A>Т.е. имеется очень много файлов, в имени файла есть три даты: начало и конец периода и дата создания (но вместе с тем, уникальность имени не гарантирована). Данные из этих файлов загружаются моей программой в таблицу бд. Записей может быть больше 20 млрд. A>Идея есть такая. A>Посчитать crc32 по строке имя файла + размер файла.
если вы добавите к любому файлу crc32 и потом заново посчитаете crc32 то вы удивитесь.
A>Затем из четырёх байт crc32 сделать 3, например помножив 0 и 1 байт crc32, эти 3 байта сделать старшими в unsigned long long int моего идентификатора, ну а нижние 5 байтов использовать как место для счетчика порядкового номера записи каждого файла... A>Вопрос собственно в том, здраво ли это звучит и как именно установить 3 старший байта и потом инкриминировать 5 нижних отдельно от всех 8 байт... A>надеюсь сформулировал понятно...)
Для 20млрд записай база будет под терабайт.
Re[2]: Сделать уникальный идентификатор для записи
Здравствуйте, kov_serg, Вы писали:
_>Уникальный идентификатор в бд может создавать сама бд.
Средствами БД ([UID] [bigint] IDENTITY(1,1) NOT NULL) не подходит... Гружу в таблицу через oledb интерфейс IRowSetFastLoad в 12 потоков (сразу 12 файлов) и если использовать автоинкрементное поле, скорость загрузки падает с 5-7ГБ/мин до 1,2ГБ/мин, что неприемлемо....
_>А если надо привязать к содержимому файла то чем обычные hash-ы не угодили md5,sha1,sha256,... _>если вы добавите к любому файлу crc32 и потом заново посчитаете crc32 то вы удивитесь.
это понятно, удивляться не буду) наверно я не совсем понятно выразился. мне не нужно считать какой-либо хэш по самому файлу, идея была в том чтобы сделать максимально уникальную строку, например из имени файла и его размера (размер + имя уникально в наборе загружаемых файлов) и по этой строке посчитать самый быстрый и маленький (по размеру) хэш (думаю crc32 самый подходящий), а потом использовать полученный хэш как часть уникального идентификатора, а вторая часть была бы просто порядковым номером записи в конкретном файле...
_>Для 20млрд записай база будет под терабайт.
да не просто ТБ, а несколько ТБ — 5-6... это как бы тоже понятно)
В принципе вот так вроде работает...
unsigned long long int uid = crc32c(0, (const unsigned char*)sStr2Crc32.c_str(), sStr2Crc32.size());
BYTE* p = (BYTE*)& uid;
p[7] = p[3];
p[6] = p[2];
p[5] = p[0] * p[1];
uid &= 0xFFFFFFFF00000000;
uid++;
...
Теперь 3 старших байта unsigned long long int содержат crc32 (чуть урезанную)), а 5 младших счетчик...
Здравствуйте, .alex, Вы писали:
A>Здравствуйте, kov_serg, Вы писали:
_>>Уникальный идентификатор в бд может создавать сама бд. A>Средствами БД ([UID] [bigint] IDENTITY(1,1) NOT NULL) не подходит... Гружу в таблицу через oledb интерфейс IRowSetFastLoad в 12 потоков (сразу 12 файлов) и если использовать автоинкрементное поле, скорость загрузки падает с 5-7ГБ/мин до 1,2ГБ/мин, что неприемлемо....
_>>А если надо привязать к содержимому файла то чем обычные hash-ы не угодили md5,sha1,sha256,... _>>если вы добавите к любому файлу crc32 и потом заново посчитаете crc32 то вы удивитесь. A>это понятно, удивляться не буду) наверно я не совсем понятно выразился. мне не нужно считать какой-либо хэш по самому файлу, идея была в том чтобы сделать максимально уникальную строку, например из имени файла и его размера (размер + имя уникально в наборе загружаемых файлов) и по этой строке посчитать самый быстрый и маленький (по размеру) хэш (думаю crc32 самый подходящий), а потом использовать полученный хэш как часть уникального идентификатора, а вторая часть была бы просто порядковым номером записи в конкретном файле...
_>>Для 20млрд записай база будет под терабайт. A>да не просто ТБ, а несколько ТБ — 5-6... это как бы тоже понятно)
A>В принципе вот так вроде работает... A>
A>unsigned long long int uid = crc32c(0, (const unsigned char*)sStr2Crc32.c_str(), sStr2Crc32.size());
A>BYTE* p = (BYTE*)& uid;
A>p[7] = p[3];
A>p[6] = p[2];
A>p[5] = p[0] * p[1];
A>uid &= 0xFFFFFFFF00000000;
A>uid++;
A>...
A>
A>Теперь 3 старших байта unsigned long long int содержат crc32 (чуть урезанную)), а 5 младших счетчик...
Не понятно какую проблему вы решаете...
Если вам нужен гарантированно уникальный Id который может независимо генериться для любого INSERT`а в базу, то лучше сгенерить какой-нибудь MD5 от уникального набора параметров файла. MD5 алгоритм очень быстрый.
Если вы можете использовать инкремент и назначать файлам порядковый номер 1, 2, 3... , то зачем вам вообще crc32?
Здравствуйте, .alex, Вы писали: A>Вопрос собственно в том, здраво ли это звучит и как именно установить 3 старший байта и потом инкриминировать 5 нижних отдельно от всех 8 байт...
Разница в том, что они не позволяют взять произвольный файл и однозначно его опознать с помощью хеширования. Надёжность хешей от взлома это отдельный вопрос, но применительно к crc32 здесь даже разговаривать не о чем.
В определённом смысле размеры файлов или других блоков данных это тоже пространства имён.
Размер файла хорош тем, что для его получения в отличие от того же хеширования не нужно производить никаких вычислений. Но если это база данных, то соединять размер или хеш с другой информацией имеет ряд побочных отрицательных эффектов и ни одного положительного.
1) в базе данных появляются лишние данные занимающие её объём
2) теряется эффект индексации поля "размер файла"
Так же стоит учитывать, что один и тот же файл может лежать в разных местах, то есть в urn он в одном экземпляре, а в url во множестве.
table:urn
..id
..size
..crc32 <= хеш
..md5 <= хеш
..sha1 <= хеш
..и так далее
table:url
..urn <= ссылка на id table:urn
..scheme
..login
..password
..host
..port
..path
..query
..fragment
По поводу хешей ещё скажу, что не важно примитивен ли алгоритм или используется более продвинутый, но лучше всего производить считывание данных лишь один раз. Обычно считывание с диска в оперативную память происходит кусками (chunk), в этот момент текущий кусок можно отправить сразу всем обработчикам вычисляющим различные хеши.
Re[3]: Сделать уникальный идентификатор для записи