Хранение UUID в базе данных HSQLDB - PullRequest
7 голосов
/ 15 декабря 2009

Я хочу сохранить UUID, созданные с использованием java.util.UUID в базе данных HSQLDB.

Очевидный вариант - просто сохранить их как строки (в коде они, вероятно, будут просто обрабатываться как таковые), т.е. varchar (36).

Какие еще варианты я должен рассмотреть для этого, учитывая такие вопросы, как размер базы данных и скорость запросов (ни одна из которых не вызывает серьезного беспокойства из-за объема используемых данных, но я хотел бы рассмотреть их как минимум)

Ответы [ 5 ]

8 голосов
/ 15 декабря 2009

У вас есть несколько вариантов:

  • Сохраните его как VARCHAR (36), как вы уже предложили. Это займет 36 байтов (288 бит) памяти на UUID, не считая служебных данных.
  • Сохранять каждый UUID в двух столбцах BIGINT, один для младших разрядов и один для старших разрядов; используйте UUID # getLeastSignificantBits () и UUID # getMostSignificantBits () , чтобы захватить каждую часть и сохранить ее соответствующим образом. Это займет 128 бит памяти на UUID, не считая каких-либо накладных расходов.
  • Хранить каждый UUID как ОБЪЕКТ; это сохраняет его как двоичную сериализованную версию класса UUID. Я понятия не имею, сколько места это занимает; Мне нужно было выполнить тест, чтобы увидеть, что такое сериализованная форма Java UUID по умолчанию.

Достоинства и недостатки каждого подхода основаны на том, как вы передаете UUID вокруг своего приложения - если вы передаете их в виде их строковых эквивалентов, то недостаток в том, чтобы удвоить емкость хранилища для VARCHAR (36) подход, вероятно, перевешивается тем, что нет необходимости конвертировать их каждый раз, когда вы выполняете запрос или обновление БД. Если вы передаете их как родные UUID, то метод BIGINT, вероятно, требует довольно много накладных расходов.

О, и это приятно, что вы рассматриваете вопросы скорости и места для хранения, но, как сказали многие лучше меня, также хорошо, что вы понимаете, что они не могут быть критически важными, учитывая объем данных вашего приложения. будет хранить и поддерживать. Как всегда, микрооптимизация ради производительности важна только в том случае, если это не приводит к неприемлемым затратам или производительности. В противном случае эти две проблемы - пространство хранения UUID и время, необходимое для их обслуживания и запроса в БД, - имеют относительно низкое значение, учитывая дешевую стоимость хранения и способность индексов БД сделать вашу жизнь намного легче. :)

7 голосов
/ 15 декабря 2009
  1. Я бы порекомендовал char(36) вместо varchar(36). Не уверен насчет hsqldb, но во многих СУБД char немного быстрее.

  2. Для поиска, если СУБД умна, вы можете использовать целочисленное значение, чтобы «приблизиться» к вашему UUID.

Например, добавьте столбец int в таблицу, а также символ (36). Когда вы вставляете в свою таблицу, вставьте uuid.hashCode () в столбец int. Тогда ваши поиски могут быть такими

WHERE intCol = ? and uuid = ?

Как я уже сказал, если hsqldb умный как сервер mysql или sql, он сузит поиск по intCol, а затем сравнит не более нескольких значений по uuid. Мы используем этот трюк для поиска по миллионам + таблиц записей по строкам, и это по сути так же быстро, как поиск целых чисел.

5 голосов
/ 01 февраля 2017
2 голосов
/ 17 января 2010

Использование BINARY (16) - еще одна возможность. Меньше места для хранения, чем у типов символов. Используйте CREATE TYPE UUID .. или CREATE DOMAIN UUID .. как предложено выше.

0 голосов
/ 15 декабря 2009

Я думаю, что проще всего было бы создать свой собственный домен, создав, таким образом, собственный UUID-тип (на самом деле не тип, но почти).

Вам также следует подумать над ответом на этот вопрос (особенно, если вы планируете использовать его вместо «обычного» первичного ключа)

INT, BIGINT или UUID / GUID в HSQLDB?

HSQLDB: создание и манипулирование доменом

...