Firebird + Lazarus+ GUID

Модератор: Модераторы

Firebird + Lazarus+ GUID

Сообщение wofs » 29.05.2018 17:23:11

Доброго дня.
Собственно как хранить в БД/обрабатывать на клиенте?
Если хранить на сервере как VARCHAR(32), то довольно накладно для первичного ключа (беспокоит размер индекса).
Если хранить в домене:
Код: Выделить всё
CREATE DOMAIN GUID AS
CHAR(16) CHARACTER SET OCTETS
COLLATE OCTETS;

То совершенно непонятно как обрабатывать на клиенте (например, апдейт записи).

Использую стандартный SQLQuery, запросы формирую с параметрами.

Добавлено спустя 5 минут 30 секунд:
Читал статейку: http://www.ibase.ru/test2/, но там предлагается переворачивать GUID после генерации для хранения с целью уменьшения размера индекса, но как то совсем велосипед...
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение wadman » 29.05.2018 17:35:04

32 символа жирновато... https://firebirdsql.org/refdocs/langref ... _uuid.html
wadman
постоялец
 
Сообщения: 109
Зарегистрирован: 18.10.2016 15:54:28

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 29.05.2018 17:36:37

wadman писал(а):32 символа жирновато... https://firebirdsql.org/refdocs/langref ... _uuid.html

Согласен, но при хранении как CHAR(16) совершенно непонятно как использовать его на клиенте (например, для апдейта записи).

wofs писал(а):Если хранить в домене:

Код: Выделить всё
CREATE DOMAIN GUID AS
CHAR(16) CHARACTER SET OCTETS
COLLATE OCTETS;


То совершенно непонятно как обрабатывать на клиенте (например, апдейт записи).
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение wadman » 29.05.2018 17:37:58

Оказалось, что в той статье как раз об этом. :)

Гуид вообще сам по себе велосипед, который обычно применяют при репликации.
Чем bigint не угодил?

Добавлено спустя 1 минуту 27 секунд:
wofs писал(а):например, для апдейта записи

Как обычно: при вставке сгенерировал, сконвертировал и вставил. Далее работаешь как с обычным ключевым полем без каких-либо конвертаций.
При необходимости (для отображения человеку) - можно и вернуть в обратный вид на лету (обратной функцией).
wadman
постоялец
 
Сообщения: 109
Зарегистрирован: 18.10.2016 15:54:28

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 29.05.2018 17:50:12

wadman писал(а):Чем bigint не угодил?

Несколько автономных клиентов с периодической синхронизацией с головной БД. Нужна уникальность ключей при добавлении записей в оффлайн.
wadman писал(а):Как обычно: при вставке сгенерировал, сконвертировал и вставил. Далее работаешь как с обычным ключевым полем без каких-либо конвертаций.

Проблема в том, что если хранить GUID на сервере в CHAR(16), то при выборке на клиенте получаем белиберду вроде
Код: Выделить всё
SELECT * FROM TABLE
aDataSet.FieldByName('ID').AsString

//return: ????K??m2(?

И я не могу передать это в параметр запроса на изменение обновить запись
Код: Выделить всё
UPDATE TABLE SET NAME=:NAME WHERE ID=:ID

точнее передать то могу, только запись не обновиться.
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение wadman » 29.05.2018 18:39:47

wofs писал(а): то при выборке на клиенте получаем белиберду вроде

База в юникоде? Я таким не занимался, но на лицо проблема с кодировкой.
wadman
постоялец
 
Сообщения: 109
Зарегистрирован: 18.10.2016 15:54:28

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 29.05.2018 18:45:24

wadman писал(а):База в юникоде? Я таким не занимался, но на лицо проблема с кодировкой.

Да, UTF8.
Суть проблемы я уловил и она такова - при конвертации
Код: Выделить всё
SELECT * FROM TABLE
aDataSet.FieldByName('ID').AsString

датасет честно пытается конвертировать 16 байт
Код: Выделить всё
// GUID хранится в БД так:
157 252 250 150 230 170 75 170 190 240 109 50 40 178 139 142

в строку и получаем, что получаем.

Добавлено спустя 27 минут 27 секунд:
Единственное, что получилось - хранить как CHAR(32)
Код: Выделить всё
CREATE DOMAIN GUID AS
CHAR(32) CHARACTER SET OCTETS
COLLATE OCTETS;

и генерировать GUID в триггере:
Код: Выделить всё
   IF (NEW.ID IS NULL) THEN
    NEW.ID = REPLACE(UUID_TO_CHAR(GEN_UUID()),'-','');
// return: A626FF232E03427D948D65A39155DCB7


Тогда работа с GUID ничем не отличается от работой со строками. Придется смириться с бОльшим размером индекса.
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение Vadim » 30.05.2018 16:33:25

wofs
Ещё вот здесь про GUID упоминали:
http://www.firebirdsql.org/manual/ru/mi ... es-ru.html
Vadim
долгожитель
 
Сообщения: 2983
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 30.05.2018 21:08:53

Vadim писал(а):wofs
Ещё вот здесь про GUID упоминали:

Это я видел. Тот вариант не отличается от моего (CHAR(32)).
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение serbod » 31.05.2018 13:24:18

А почему decimal или int64 не подходят? int64 это не так уж и мало, даже очень дохрена на самом деле. Особенно, если не рандомно генерить, а по алгоритму.
Аватара пользователя
serbod
постоялец
 
Сообщения: 350
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 31.05.2018 16:38:36

serbod писал(а):А почему decimal или int64 не подходят? int64 это не так уж и мало, даже очень дохрена на самом деле. Особенно, если не рандомно генерить, а по алгоритму.

Нужна уникальность номера при условии генерации оного на оффлайн клиентах.
---
ps. Куда-то Виталий пропал с балалайкой...
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: Firebird + Lazarus+ GUID

Сообщение serbod » 31.05.2018 17:37:42

wofs писал(а):Нужна уникальность номера при условии генерации оного на оффлайн клиентах.

1-2 байта на номер клиента (филиала, экземпляра) и остальные 6 байтов - синтетический автоинкремент. Перед началом работы делаешь запрос максимального номера для данного экземпляра и от него дальше танцуешь.
Аватара пользователя
serbod
постоялец
 
Сообщения: 350
Зарегистрирован: 16.09.2016 11:03:02
Откуда: Минск

Re: Firebird + Lazarus+ GUID

Сообщение olegy123 » 31.05.2018 23:27:20

Я разбивал на два int64 так как (UUID) is a 128-bit number.
это двух 64битное число можно индексировать.

Добавлено спустя 1 минуту 57 секунд:
wofs писал(а):Нужна уникальность номера при условии генерации оного на оффлайн клиентах.
Генерация UUID дает уникальность всегда.

Добавлено спустя 4 минуты 56 секунд:
вообще любые данные можно сериализовать -> перевести данные в виде потока данных,
два int64 подходят для упаковки данных GUUID без потери, так же можно восстановить GUUID из двух int64 .

Добавлено спустя 2 минуты 50 секунд:
serbod писал(а):1-2 байта на номер клиента (филиала, экземпляра) и остальные 6 байтов - синтетический автоинкремент. Перед началом работы делаешь запрос максимального номера для данного экземпляра и от него дальше танцуешь.
не всегда это подходит, бывает когда данные создаются без привязки к чему либо.. но нужно обеспечить уникальность в рамках земного шара/вселенной.
olegy123
энтузиаст
 
Сообщения: 1120
Зарегистрирован: 25.02.2016 12:10:20

Re: Firebird + Lazarus+ GUID

Сообщение Снег Север » 01.06.2018 12:30:19

olegy123 писал(а):не всегда это подходит, бывает когда данные создаются без привязки к чему либо.. но нужно обеспечить уникальность в рамках земного шара/вселенной.
Универсальное правило - не множить сущности. Закладывать в программе возможности выхода на межгалактический рынок - не самая удачная идея... :D
Аватара пользователя
Снег Север
энтузиаст
 
Сообщения: 1336
Зарегистрирован: 27.11.2007 16:14:47

Re: Firebird + Lazarus+ GUID

Сообщение wofs » 03.06.2018 13:45:58

Спасибо всем за информацию к размышлению.
Аватара пользователя
wofs
постоялец
 
Сообщения: 375
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

След.

Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

Рейтинг@Mail.ru