Надлежащая нормализация в СУБД означает распространение таблиц. Целочисленные поля могут хранить ортогональные данные в виде битов - может ли это использоваться как замена дополнительной таблицы, не жертвуя реляционной целостностью?
Может ли побитовая математика использоваться для отношений "один ко многим" в SQL?
Ответ 1
Ответ на ваш вопрос - "нет". Битовые поля жертвуют реляционной целостностью по той простой причине, что у вас есть сущности в базе данных, которые не имеют соответствующих таблиц.
Тем не менее, многие базы данных предлагают поддержку для этого, как правило, через "бит" типа данных. У Mysql есть еще более сильная поддержка с типом данных "set".
Основная проблема заключается в том, что вы ничего не знаете о элементах в наборе - что такое полное имя, когда оно было добавлено в базу данных и т.д. (Enums обходят часть проблемы с именами.) Кроме того, размер набора ограничен. У вас может быть пример, где все ограничено. Однако пример Мэтта скорее подчеркивает проблему здесь. У вас может быть список посещенных континентов. Однако, когда вы переключаетесь на посещаемые страны, подход, безусловно, совершенно другой, потому что число стран больше не вписывается ни в одно "слово". Хотели бы вы, чтобы ваша система относилась к континентам совсем иначе, чем страны в этом отношении? Вы хотите, чтобы ваши проектные решения были ограничены лимитом 32 или 64 бита в компьютерном слове?
И, наконец, вы, похоже, рассматриваете распространение таблиц как проблему. Распространение таблиц на самом деле является решением. Все данные об объектах хранятся в таблицах, а не распространяются через систему. Вы можете хранить информацию о экземплярах объекта, например, когда экземпляр был создан, как он мог измениться с течением времени и т.д. Сущность для "континентов", вероятно, будет использоваться всякий раз, когда кто-то хочет континент.
Рассмотрите, что происходит в системе, где два разных разработчика решают развить свои собственные бит-маски для континентов, но они перевели континенты в другом порядке. С хорошо разработанной реляционной базой данных (что означает, что отношения внешнего ключа явно объявлены в определении таблицы), такая путаница не может возникнуть.
Ответ 2
Для отношения "один ко многим", где "много" имеет небольшое количество известных значений, отношения могут быть сохранены как битмаски в родительской таблице как целое число, заменяя необходимость в дополнительной таблице.
Скажем, у нас есть стол Person и wed, чтобы знать, сколько континентов посетил человек. Wed начните с присвоения каждому континенту "ортогонального" значения бит. В С#, перечисление является хорошим выбором для этого:
[Flags]
public enum JobAdvertisingRegion
{
NorthAmerica = 1, // or 1 << 0
SouthAmerica = 2, // 1 << 1
Europe = 4, // 1 << 2
Asia = 8, // 1 << 3
Africa = = 16, // 1 << 4
Australia = 32, // 1 << 5
Anarctica = 64 // 1 << 6
}
В таблице "Люди" может быть просто столбец "Контекст". Чтобы указать, что человек посетил Европу и Азию:
UPDATE Persons SET Continents = (4 + 8) WHERE Id = whatever
Чтобы найти людей, которые посетили Антарктиду, мы используем поразрядную математику:
SELECT * FROM Persons WHERE Continents & 64 = 64
Поиск людей, которые посетили как Африку, так и Азию:
SELECT * FROM Persons WHERE Continents & (16 + 8) = (16 + 8)
Поиск лиц, которые посетили Австралию или Южную Америку:
SELECT * FROM Persons WHERE Continents & (32 + 2) != 0
Один недостаток заключается в том, что, хотя целочисленные столбцы индексируются в SQL, их битовые компоненты не являются. Некоторые оптимизации, чтобы обойти это, для вышеуказанных запросов:
SELECT * FROM Persons WHERE Continents & 64 = 64 AND Continents >= 64
SELECT * FROM Persons WHERE Continents & (16 + 8) = (16 + 8) AND Continents >= (16 + 8)
SELECT * FROM Persons WHERE Continents & (32 + 2) != 0 AND Continents >= 2
Ответ 3
Хорошо, я пойду против (в настоящее время) популярного мнения здесь, просто заявив несколько фактов
- SQL и реляционная модель не соответствуют не.
- Реляционная модель (теория) работает с реляционными переменными, так называемыми relvars.
- Базы данных SQL используют таблицы.
- Таблицы и реверты не совпадают, но могут быть - для всех практических целей.
- Чтобы использовать теорию реляционного моделирования, таблицы должны представлять relvars.
-
Для таблицы, представляющей реляционную переменную, должно быть верно следующее:
- Строки не имеют порядка
- Столбцы не имеют порядка
- Нет повторяющихся строк
- Каждое пересечение столбцов и строк имеет только одно значение типа, определенного столбцом
- Нет специальных скрытых столбцов (идентификаторы строк, идентификаторы объектов...)
Итак, вы можете делать много вещей с таблицами и SQL, которые выходят за рамки теории реляционного дизайна, но вы теряете преимущества "реляционного"...
Технически ваш пост (вопрос) имеет два ответа.
- Да, к названию сообщения.
- Нет, к телу сообщения.