Используя побитовый флаг для первичного ключа? - PullRequest
4 голосов
/ 09 июля 2009

Я проектирую базу данных и думал о необходимости отношений один ко многим. Традиционно я выполнил обычное PK (как GUID) и установил отношения, но вместо этого мне было интересно, почему бы не использовать побитовый флаг в качестве PK.

Связь будет потеряна, но сами данные будут описывать эту связь.

Пример - у меня есть таблица групп и таблица пользователей. Пользователи могут иметь 1 или более групп:

+------------------------+
| Groups                 |
+------------------------+
| PK      | Display Name |
+---------+--------------+
| 1       | Group A      |
| 2       | Group B      |
| 4       | Group C      |
+---------+--------------+

+------------------------+
| Users                  |
+------------------------+
| Name    | Groups       |
+---------+--------------+
| Fred    | 1            | // Fred is only in Group A
| Jim     | 3            | // Jim is in Groups A & B
| Sam     | 7            | // Sam is in all Groups
+---------+--------------+

Мысли, комментарии и предложения по этому дизайну, пожалуйста?

Ответы [ 6 ]

5 голосов
/ 09 июля 2009

Я бы не рекомендовал использовать такие битовые флаги.Во-первых, вы нарушили возможность простого объединения этих таблиц, поэтому определение членства в группах а) займет больше времени, б) будет более сложным и в) возможно, потребует более полного сканирования таблиц или, по крайней мере, сканирования индекса.

4 голосов
/ 09 июля 2009

У тебя кончились цифры довольно быстро. Если у вас есть 64 группы, вы уже используете 64 бит. Мне страшно подумать, что произойдет, если у вас будет миллион групп.

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

2 голосов
/ 09 июля 2009

плохая идея ... как индекс будет работать вообще? пришлось бы сканировать и делать расчеты по каждому значению ...

Допустим, вы хотите знать всех пользователей в группе X ... вам нужно будет запустить функцию в каждой строке, чтобы определить, были ли они в этой группе, а не просто выполнить очень быстрый поиск по индексу найди свой ответ.

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

2 голосов
/ 09 июля 2009

Не хорошо ИМО. Это типичное отношение «многие ко многим». Если PK 32-битный, то один пользователь может быть в макс. 32 группах. Зачем ограничивать дизайн?

// Сэм во всех группах.

Допустим, вы изменили дизайн и сделали PK 4 бита вместо 3. Сейчас Сэм во «всех группах» или только в группах 0-7?

Какой выигрыш?

Как бы вы писали запросы (объединения)? Я думаю, у вас будут проблемы с этим дизайном.

2 голосов
/ 09 июля 2009

Хорошая идея, не могу понять, какую пользу принесло бы это в реляционной базе данных. Я думаю, что если вы работаете с SQL, вам в основном нужно использовать стандартные ключи, иначе какой смысл в вашем дорогом хранилище?

Возможно, это было бы лучше подходит для файлового хранилища, где каждая таблица находится в отдельном файле. Или используйте его в качестве дополнительного столбца, но не указывайте в нем первичный ключ.

P.S. Не упадет ли это, если два пользователя будут в одной группе?

Ryan

0 голосов
/ 09 июля 2009

Я недавно видел GUID в качестве первичных ключей, и я думаю, что это ужасная идея. GUID расшифровывается как «Глобально уникальный идентификатор», то есть это идентификатор, чей шанс повторного бинга повторяется, если он неправильно цитирует Брокмейера в его книге OLE «так же, как группа атомов, спешащих вместе в пустом пространстве, образуя маленький орех ».

Существуют веские причины для использования идентификаторов GUID, если вам действительно нужно что-то глобально уникальное, но большинство ключей базы данных должны быть уникальными только относительно рассматриваемой базы данных. В этом случае последовательного сгенерированного целочисленного ключа часто достаточно, и он потребляет намного меньше ресурсов. На самом деле, ни идентификаторы последовательности, ни GUID не имеют никакого внутреннего значения, поэтому действительно лучше, если вы можете использовать элементы, которые действительно идентифицируют рассматриваемый объект как первичный ключ, если вы можете (хотя существует школа, которая говорит, что все элементы должен иметь независимый от содержимого ключ, такой как sequence или даже GUID).

Битовые поля имеют несколько обязательств в качестве первичных ключей. Как уже упоминалось, вы можете решить, что вам нужны дополнительные биты. Вы можете столкнуться с столкновениями. Базы данных, как правило, имеют плохую побитовую функциональность и даже не являются переносимыми. И, наконец, алгоритмы индексирования для выбранной вами базы данных могут быть не в состоянии хорошо оптимизировать битовые ключи.

...