Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > как обеспечить уникальность текстовых blob-полей?


Автор: Чoо 17.8.2010, 20:36
Первое, что приходит в голову, это добавить в таблицу поле blobCRC (unique) в которое перед записью текстового блоб-поля пытаться записать вычисленную пользовательским приложением, контрольную сумму. Если запись удалась, то можно записывать и блоб-поле, если нет, то текущая запиь не является уникальной, о чем сообщается пользователю.
Или есть более изящные варианты?

на всякий случай, сообщаю, что в этом поле текста будет существенно меньше 32 КБайт. 

впринципе вижу и второй вариант, формировать SQL запрос:
Код

select case when exists (select null from TBL T 
                             where T.BLOBFIELD = 'какой-то текст')
                  then 1 else 0  end 
          FIND
from TBL

но в этом случае:
1. Надо передавать текст на сервер, что бы проверить есть ли такой
2. Надо еще раз передавать, если его все-таки нет
3. Сервер в поисках блоб-поля будетп росматривать все записи с первой до тех пор, пока не закончатся все записи или не будет найден такой же текст. 
Вобщем как-то неоптимально.. 
Посоветуйте что-нибудь?

Автор: Frees 17.8.2010, 21:05
а зачем именно Blob может Varchar и уникальный индекс по этому полю


Цитата(Чoо @  17.8.2010,  23:36 Найти цитируемый пост)
вычисленную пользовательским приложением, контрольную сумму. Если запись удалась, то можно записывать и блоб-поле, если нет, то текущая запиь не является уникальной, о чем сообщается пользователю.

у контрольной суммы могут быть коллизии...

Автор: Чoо 17.8.2010, 21:16
Frees, коллизий боюсь.. да.. а varchar не утраивает тем, что при кодировке win1251 уникальный индекс можно будеть создать, только если строка будет иметь длину не больше 252 символов (252 байта). в firebird 1.5 вроде такое ограничение. использую 2.1, но по этому поводу ни какой информации не нашел.
Хоть я и использую эту кодировку, мне 252 символов точно мало.

Автор: Frees 17.8.2010, 21:48
еще можно сделать сохраненку в нее 1 раз передаешь текст она его сперва ищет (без запроса на поиск помоему не обойтись), а если не найдет то вставляет.

или через Check

Код

CREATE TABLE TABLE1 (
    ID  INTEGER,
    BLOB_FIELD        BLOB SUB_TYPE 1 SEGMENT SIZE 16384
);

ALTER TABLE TABLE1 ADD CHECK (not exists(select * from TABLE1 w where w.BLOB_FIELD = new.BLOB_FIELD));


Добавлено через 5 минут и 11 секунд
если через чек то в случае повтора будет исключение, если через сохраненку то можно сделать, что бы она просто возвращала вставлена или нет запись.

Добавлено через 8 минут и 40 секунд
Цитата(Чoо @  17.8.2010,  23:36 Найти цитируемый пост)
Первое, что приходит в голову, это добавить в таблицу поле blobCRC (unique) в которое перед записью текстового блоб-поля пытаться записать вычисленную пользовательским приложением, контрольную сумму. Если запись удалась, то можно записывать и блоб-поле, если нет, то текущая запиь не является уникальной, о чем сообщается пользователю.

вообще хорошая идея, только помимо crc еще хранить длину текста тогда вероятность коллизии буде стремиться к 0.


Автор: Чoо 17.8.2010, 22:46
Frees, вариант с check для многопользовательской среды не годится (читаю в книге Хеллен Борри, стр. 314: 
Цитата

"вы не должны использовать выражения, которые сравнивают значения со значениями из других строк этой же таблицы или других таблиц, потому что любая строка, отличная от текущей, может находиться в процессе изменения или удаления в другой транзакции"
) => как начну делать многопользовательский клиент этот вопрос всплывет снова.
Может я не правильно что-то понял... 

А что вы понимаете под сохраненкой?

Добавлено через 1 минуту и 17 секунд
Цитата(Frees @  17.8.2010,  21:48 Найти цитируемый пост)
вообще хорошая идея, только помимо crc еще хранить длину текста тогда вероятность коллизии буде стремиться к 0.

однако хоть и не большая, но есть вероятность коллизии. все-таки это неприемлимо.

Автор: Deniz 18.8.2010, 07:22
Чoо, гарантированную уникальность обеспечит только уникальный индекс, никакие триггеры, чеки, процедуры и т.д. тут не помогут.
Сл-но, смотрим по каким типам полей (и размеру) можно сделать такой индекс.
Получаем, что нужен какой-то алгоритм, который гарантировано для blob сделает уникальную строчку (желательно не сильно длинную).
Вот и все, копайте в сторону 
Цитата(Чoо @  17.8.2010,  22:36 Найти цитируемый пост)
добавить в таблицу поле blobCRC (unique)
.
А вот реализация добавления/изменения такой пары (blob + blobCRC), это на любителя.

Автор: Akella 18.8.2010, 09:21
Цитата(Чoо @  17.8.2010,  21:16 Найти цитируемый пост)
не больше 252 символов

читай RN, на сколько мне известно, то уже больше

Добавлено через 1 минуту и 43 секунды
Цитата(Frees @  17.8.2010,  21:48 Найти цитируемый пост)
вообще хорошая идея, только помимо crc еще хранить длину текста тогда вероятность коллизии буде стремиться к 0.

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

Добавлено через 2 минуты и 9 секунд
А если уж длина совпала, то тогда и значение поля можно проверять.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)