Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.06.12;
Скачать: [xml.tar.bz2];

Вниз

Почти уникальный ID   Найти похожие ветки 

 
novichek   (2011-03-04 16:22) [0]

Преследуя репликацию, где данные с клиентов могут передаваться разным способом, необходимо генерировать уникальный ID.

локальное отделение вероятно будет иметь не более 10 ПК.

Как вы думаете, можно ли использовать для генерации уникального ID записи данную функцию?

ID:= genUniID(kodOtdela)
...

function genUniID(id: byte): Int64;
var
 x: Int64;
 y, m, d, ss: Word;
begin

 x:= id;

 DecodeDate(date, y, m, d);

 y:= y and 15;
 x:= x shl 4;
 x:= x + y;
 x:= x shl 4;
 x:= x + m;
 x:= x shl 5;
 x:= x + d;

 DecodeTime(time, y, m, d, ss);

 x:= x shl 5;
 x:= x + y;
 x:= x shl 6;
 x:= x + m;
 x:= x shl 6;
 x:= x + d;
 x:= x shl 7;
 x:= x + ss;

 x:= x shl 7;

 result:= x + random(128);

end;


это первое что пришло в голову..

может есть какие красивые варианты?
пока опыта ноль..


 
clickmaker ©   (2011-03-04 16:26) [1]

СУБД какая?


 
RWolf ©   (2011-03-04 16:27) [2]

сгенерировать GUID, конечно.


 
Медвежонок Пятачок ©   (2011-03-04 16:27) [3]

а может просто CoCreateGuid?


 
novichek   (2011-03-04 16:31) [4]

FireBird как и посоветовали.

ну как понимаю GUID будет храниться в строке..

как то ключеврой индекс не хочется иметь строку..


 
Сергей М. ©   (2011-03-04 16:33) [5]


> GUID будет храниться в строке


Как будешь хранить - так и будет храниться.
Не хочешь в строке - храни в Int64


 
RWolf ©   (2011-03-04 16:34) [6]

typedef struct _GUID {
   unsigned long Data1;
   unsigned short Data2;
   unsigned short Data3;
   unsigned char Data4[8];
} GUID;


и где тут строка?


 
Jeer ©   (2011-03-04 16:34) [7]

Составной PK


 
Inovet ©   (2011-03-04 16:39) [8]

> [4] novichek   (04.03.11 16:31)
> FireBird как и посоветовали.

Генераторы в нём для этого предназначены.


 
novichek   (2011-03-04 16:56) [9]

Inovet ©, так а что генераторы? в каждом отделе свой сервер. потом общие данные будут стекаться на главный. ещё правда не знаю как, репликации в FireBird нету, прийдется что то мудрить своё..

RWolf © , я х.з., читал умные статьи:
http://www.ibase.ru/devinfo/test2.htm
"Некоторые сервера позволяют хранить GUID в его двоичном представлении, размером 16 байт. В IB нет возможности сохранить двоичное значение в строке, а blob для таких целей использовать будет неэффективно. Поэтому выход остается один - хранить GUID как строку."


 
Jeer ©   (2011-03-04 16:58) [10]


> Поэтому выход остается


Составной PK - еще раз.


 
Противный   (2011-03-04 16:58) [11]

> Сергей М. ©   (04.03.11 16:33) [5]
> > GUID будет храниться в строке
> Как будешь хранить - так и будет храниться.
> Не хочешь в строке - храни в Int64


GUID 128-битный. Хотя, если отрезать половину, то влезет. Но надо знать откуда резать, а то уникальности не получится. То есть, есть ньюансы...

> novichek   (04.03.11 16:22)  Как вы думаете, можно ли использовать для генерации уникального ID записи данную функцию?

Использовать время для генерации первичного ключа - не лучшее решение. Точнее, плохое решение. Или ты готов гарантировать точное время на всех компьютерах?


 
clickmaker ©   (2011-03-04 17:01) [12]

главное, чтобы время было одинаковое


 
Sergey13 ©   (2011-03-04 17:05) [13]

> [7] Jeer ©   (04.03.11 16:34)
> Составной PK
+100500. Чего мудрить то?


 
Inovet ©   (2011-03-04 17:06) [14]

> [9] novichek   (04.03.11 16:56)
> прийдется что то мудрить своё..

Номер сервера в дополнение.


 
Сергей М. ©   (2011-03-04 17:08) [15]


> если отрезать половину


Нафига резать ?
Два Int64-поля в составной ключ - и всех делов.
Можно и одно char(16)-поле, указав чарсет OCTETS


 
clickmaker ©   (2011-03-04 17:12) [16]

а нафига составному быть уникальным? Уникальными должны быть составляющие


 
novichek   (2011-03-04 17:12) [17]

мда..  

Jeer ©

я пока перемалываю в голове.. не хотелось бы конечно держать составной первичный индекс.

Противный,  а вы не помните где резать?


 
Jeer ©   (2011-03-04 17:13) [18]


> не хотелось бы конечно держать составной первичный индекс.


Глупости, именно это и есть панацея в таких случаях.


 
novichek   (2011-03-04 17:15) [19]

Inovet ©, если бы я ставил может номер сервера и нормально было бы..

а так я написал, отдал софт они сами ставить будут где хотят..
развернули в локальной сетке сервер, прописали в клиентах данные соединения и вперед.

потом с этих серверов будут передавать данные на главный где будут собираться до кучи.


 
Jeer ©   (2011-03-04 17:16) [20]


> clickmaker ©   (04.03.11 17:12) [16]
>
> а нафига составному быть уникальным? Уникальными должны
> быть составляющие
>


Как Вас понимать, Саид ?

Именно составной, в рамках организации, и должен быть уникальным.
И не фик вытворять чудеса с обрезанием :)


 
clickmaker ©   (2011-03-04 17:16) [21]

я бы остановился на дате/времени + некая локальноуникальная хрень типа IP сервера. Ну, собственно в [14] предложили уже


 
clickmaker ©   (2011-03-04 17:18) [22]

> Как Вас понимать, Саид ?

составной ID - это обычно ID, образованный отношениями между сущностями. UserID - ObjectID, к примеру. Он не уникален сам по себе. Его делают уникальным состовляющие.
А вот их и надо генерить


 
Jeer ©   (2011-03-04 17:20) [23]


> предложили уже


Предложен был составной PK, как наиболее правильное решение в таких случаях.
Что в основе составного PK должно лежать - решать автору проекта.
Может у них по несколько серверов на пользователя раздают :)


 
Sergey13 ©   (2011-03-04 17:21) [24]

> [19] novichek   (04.03.11 17:15)
> а так я написал, отдал софт они сами ставить будут где хотят..

Не взлетит.

> потом с этих серверов будут передавать данные на главный где будут собираться до кучи.
Пришли адресок, может и мы чего пульнем ради женского праздника. 8-)


 
Jeer ©   (2011-03-04 17:21) [25]


> А вот их и надо генерить


Задача генерации составляющих PK решается административно-техническими методами. Здесь нет проблем.


 
clickmaker ©   (2011-03-04 17:27) [26]

> Здесь нет проблем

при репликации есть. Собственно, об ней и ветка


 
Противный   (2011-03-04 17:32) [27]

> Jeer ©   (04.03.11 17:13) [18] Глупости, именно это и есть панацея в таких случаях

Доступ к 2 полям типа Int64 медленнее, чем к одному полю типа GUID. Что-то мне подсказывает, что медленнее более, чем в 2 раза. Соответственно, все операции по индексированию и поиску...

2 novichek

Сделай в БД табличку с двумя полями:

DepartmentUniquePrefix integer
NextID integer

Там храни префикс отделения и следующий идентификатор.

А первичные ключи в таблицах сделай Int64, первые 32 бита - DepartmentUniquePrefix, вторые 32 бита - ID.

Напиши функцию по типу CreateNextID: Int64, в которой и реализуй логику генерации ключей.


 
Противный   (2011-03-04 17:46) [28]

Для ускорения процесса генерации можешь инкрементировать NextID в таблице ключиков не на 1 при каждой генерации ключа, а, например, на 10, храня в памяти текущий ID и максимальное выделенное значение. Это даст возможность сгенерировать 10 ключей, обратившись к БД всего один раз. В общем, инкремент NextID может быть переменным, и опередляться в зависимости от ожидаемых операций.

Конецептуально:

TIDGenerator = class
private
 FNextID: integer;
 FMaxID: integer;
 FDepartmentPrexif: integer;
 FBlockSize: integer;
protected
 procedure AcquireBlock;
public
 function NextID: Int64;
 property BlockSize: integer read FBlockSize write FBlockSize;
end;

procedure TIDGenerator.AcquireBlock;
begin
 BeginTransaction;
 try
   Query(SELECT NextID AS SelectedNextID FROM IDTable);
   Execute(INSERT INTO IDTable(NextID) VALUES (SelectedNextID + FBlockSize));
   FMaxID := SelectedNextID + FBlockSize;
   CommitTransaction;
 except
   RollbackTransaction;
   raise;
 end;
end;

function TIDGenerator.NextID: Int64;
begin
 if FNextID = FMaxID then
   AcquireBlock;
 Result := FDepartmentPrexif shl 32 + FNextID;
 FNextID := FNextID + 1;
end;


 
novichek   (2011-03-04 17:55) [29]

Противный, была такая идея сразу, только проблема тут в том, что на главном сервере так же могут добавлять записи под ID любого отделения.

я вот думаю надо в моей функции убрать последнее добавление случайного числа, подсчитать сколько там остается бит до 64 и генерить в конце какой-то CRC из например мак адреса сетевухи..

а если где и совпадет случайно ид и потеряется при синхронизации одна запись какого-то отделения - ну и хрен с ней (:

спасибо за помощь!


 
Противный   (2011-03-04 18:12) [30]

> novichek   (04.03.11 17:55) [29] только проблема тут в том, что на главном сервере так же могут добавлять записи под ID любого отделения.

У главного сервера должен быть свой уникальный префикс. То есть, по сути, ID записи не предназначен для хранения никакой другой инфорамции, кроме как для уникального идентифицирования записи во всей информационной системе. Поэтому каждому серверу свой уникальный префикс. Без исключений.

А если надо хранить информацию о том, от имени какого отделения создана запись - вот тут уже отдельное поле с внешним ключем на справочник отделений.


 
Inovet ©   (2011-03-04 18:31) [31]

> [30] Противный   (04.03.11 18:12)
> Поэтому каждому серверу свой уникальный префикс. Без исключений.

Зачем тогда все сложности. Пользуемся генераторами, на каждом отделении выставляем начальное значение на свой диапазон для визуального удобства, например, так:

отд  начальное     конечное
0    0000000000001 0999999999999
1    1000000000000 1999999999999
2    2000000000000 2999999999999
3    3000000000000 3999999999999
...


 
_Юрий   (2011-03-04 20:30) [32]

Guid + индекс. Первичным ключом не делать, там обычный автоникремент.
3 года работы полет нормальный.


 
Противный   (2011-03-04 20:50) [33]

> _Юрий   (04.03.11 20:30) [32] Первичным ключом не делать, там обычный автоникремент.

Как тебя понимать?

> _Юрий   (04.03.11 20:30) [32] 3 года работы полет нормальный.

Ну и? Предлагаешь везде в качестве ключей использовать GUID?


 
KilkennyCat ©   (2011-03-04 21:19) [34]


> Inovet ©   (04.03.11 18:31) [31]

дык генератор-то тогда зачем? выделить всем свой диапазон и все.


 
Inovet ©   (2011-03-04 21:26) [35]

> [34] KilkennyCat ©   (04.03.11 21:19)
> дык генератор-то тогда зачем?

Так это в ИБ ФБ терминологии генератор. Для отделения № 2 выставить начальное значение 2000000000000 и пусть растёт, предполагаем, что в таблице не будет более 1000000000000 записей. И так для каждой таблицы. Это если ИД отделения в отдельном поле не надо.


 
novichek   (2011-03-04 22:31) [36]

да тут проблема в том, что неизвестно сколько будет отделений..
отсюда непонятно как и генерить префикс сервера.
и могут в одном отделении развернуть два сервера.

все-таки думаю временной штамп + CRC мак сетевухи вполне пойдет..


 
KilkennyCat ©   (2011-03-04 22:38) [37]


> все-таки думаю временной штамп + CRC мак сетевухи вполне
> пойдет

велосипед.
я тоже недавно изобретал такой велосипед.
Спасибо, Юрий Федоров избавил от сего извращения: GUID и на этом все.


 
novichek   (2011-03-04 22:51) [38]

ну так куда 128 бит? два поля делать?

ид уникальный должен быть в нескольких таблицах.
где потом и будут например связи один ко многим..

желательно под ид иметь одно поле.. и не строку..


 
Юрий Зотов ©   (2011-03-05 00:18) [39]

Пожиратели GUID"ов, не приближайте день X.


 
KilkennyCat ©   (2011-03-05 00:44) [40]


> novichek   (04.03.11 22:51) [38]
и не строку..

а какая разница, строка или нет?


 
b z   (2011-03-05 00:55) [41]

Ид не обязан быть ключом для репликации, и наоборот.


 
_Юрий   (2011-03-05 01:04) [42]


> Противный   (04.03.11 20:50) [33]
>
> > _Юрий   (04.03.11 20:30) [32] Первичным ключом не делать,
>  там обычный автоникремент.
>
> Как тебя понимать?
>
> > _Юрий   (04.03.11 20:30) [32] 3 года работы полет нормальный.
>
>
> Ну и? Предлагаешь везде в качестве ключей использовать GUID?
>


Нет. Гуид только для слияния, а связи все по инт-полю. На гуид обычный уникальный индекс


 
KilkennyCat ©   (2011-03-05 04:26) [43]


> Гуид только для слияния, а связи все по инт-полю. На гуид
> обычный уникальный индекс

масло масляное


 
Anatoly Podgoretsky ©   (2011-03-05 09:23) [44]

> Юрий Зотов  (05.03.2011 00:18:39)  [39]

Да хватит и для наших правнуков.


 
Anatoly Podgoretsky ©   (2011-03-05 09:23) [45]

> KilkennyCat  (05.03.2011 00:44:40)  [40]

А психология, слышал что это плохо.


 
Anatoly Podgoretsky ©   (2011-03-05 09:26) [46]

Кстати ничто не мешает ему быть числовым, в большинстве СУБД так и есть, а человек путает предствление с хранением, вот так и появляются, мол хранит даты в формате dd.mm.yyyy


 
Anatoly Podgoretsky ©   (2011-03-05 09:27) [47]

> KilkennyCat  (05.03.2011 04:26:43)  [43]

Хуже, два уникальных поля, одно дублирует другое, но пожирает кучу ресурсов
разного типа, это тоже психология. Запугали ребят, это мол плохо и это
плохо, а головы то нет.


 
Противный   (2011-03-05 10:28) [48]

> _Юрий   (05.03.11 01:04) [42] Гуид только для слияния, а связи все по инт-полю.

Э-э-э... переведи. Только в терминах реляционной теории. Потому что "слияние" у меня ассоциируется с другим. Не менее приятным. Но другим...

Да, и откуда взялось "инт-поле"?


 
DiamondShark ©   (2011-03-05 11:16) [49]


> novichek   (04.03.11 16:31) [4]
> FireBird как и посоветовали.

Фигню посоветовали. Впрочем, на делпхимастере другого не советуют, обычно.


>  ну как понимаю GUID будет храниться в строке.

Как я понимаю, GUID должен храниться как GUID. Нормальные СУБД имеют соответствующий тип.


> как то ключеврой индекс не хочется иметь строку.

Не имей, если не хочется.


 
Inovet ©   (2011-03-05 11:26) [50]

> [49] DiamondShark ©   (05.03.11 11:16)
> > FireBird как и посоветовали.
>
> Фигню посоветовали

Советовали в теме про обучение вообще, оказалось для реальной работы. Впрочем, можно было и MSSQL посоветовать.


 
Anatoly Podgoretsky ©   (2011-03-05 11:51) [51]

> DiamondShark  (05.03.2011 11:16:49)  [49]

Он наверно думает, что что то проиграет при увеличении с 32 до 36 байт.
Современный процессор делает миллиарды операций и замедление выполнения
запроса с 10 мс до 12 можно заметить, только многичисленными измерениями.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.06.12;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.004 c
2-1299056752
cross
2011-03-02 12:05
2011.06.12
функция или процедура


15-1298356869
Гость
2011-02-22 09:41
2011.06.12
Изменить шаблон, где можно ?


6-1237807196
FireMan_Alexey
2009-03-23 14:19
2011.06.12
Вопрос по НТТР


15-1297418426
reqyz
2011-02-11 13:00
2011.06.12
Перевести 3 строчки C++ -> Delphi


15-1298012535
Гость
2011-02-18 10:02
2011.06.12
посоветуйте Бесплатный хостинг





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский