sql булевы альтернативы типа данных - PullRequest
3 голосов
/ 21 июля 2010

В каких ситуациях вы используете внешний ключ для отдельной таблицы вместо логического (т. Е. BIT в SQL Server)

Например, вы бы заменили следующие два логических значения в этой таблице:

engine_sensors
--------------
id (int, primary key)
name (varchar(50))
fault_code (int)
display_warning (boolean) /* if fault show driver a warning */
is_test_sensor (boolean) /* ignore this sensor in diagnostic checks */

например. Здесь display_warning может не отображать предупреждение водителю, но отображать предупреждение механику, который тестирует двигатель. Так что отдельная таблица будет уместной.

is_test_sensor может быть заменен sensor_type (таблица FK to sensor_types), который имеет типы тестов, в реальном времени.

Ответы [ 9 ]

4 голосов
/ 21 июля 2010

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

Я не буду пытаться проверить мою базу данных в будущем (принцип YAGNI ), вы всегда можете изменить ее позже.

2 голосов
/ 21 июля 2010

Это зависит от того, почему вы хотите этого избежать. Вы можете просто иметь числовые поля с 0 для false и 1 для true. Не уверен, что есть какие-либо преимущества.

1 голос
/ 21 июля 2010

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

1 голос
/ 21 июля 2010

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

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

Обеспечение того, что элементы данных зависят от ключа (и ничего кроме ключа), достигается путем «нормализации» данных. Очень важно включить сюда ответ, но в Интернете есть много ссылок, которые помогут вам лучше понять нормализацию. Википедия так же хороша, как и любая другая:

http://en.wikipedia.org/wiki/Database_normalization#Normal_forms

1 голос
/ 21 июля 2010

engine_sensors

идентификатор (первичный ключ) имя код_ошибки

display_warning_engine_sensors / * если ошибка показывает водителю предупреждение * /

id (первичный ключ, FK для engine_sensors)

test_sensors / * игнорировать этот датчик при диагностических проверках * /

id (первичный ключ, от FK до engine_sensors)

Помните: коды плохие, таблицы богаты.Независимо от того, насколько противоречивым это кажется: никогда не используйте логические значения для представления достоверной информации.В реляционной модели уже есть способ представления достоверной информации, который заключается в наличии некоторого кортежа в некотором отношении, который является значением некоторого relvar (в терминах SQL: как наличие некоторой строки в таблице).

Вы не можете легко "расширять" логические значения для добавления дополнительных функций, таких как "отображать предупреждение, только если время находится в пределах диапазона [x часов - y часов].

1 голос
/ 21 июля 2010

Np.Теперь я вижу, к чему вы клоните (я думаю).

Если вы спрашиваете, что Я думаю , что вы спрашиваете, чем да, вы можете использовать FK для таблицы датчиков исписок датчиков.Как правило, это то, что я бы сделал ...

CREATE TABLE [SensorType](
[Id] [int] NOT NULL,
[Type] [int] NOT NULL,
    [DisplayWarningTo] [int] NOT NULL,
[Description] [nvarchar](100) NULL,
CONSTRAINT [PK_SensorType_Id] PRIMARY KEY (Id),
    CONSTRAINT [FK_SensorType_WarningReceivor] FOREIGN KEY (DisplayWarningTo) REFERENCES WarningReceivor(Id)    
 );

CREATE TABLE [WarningReceiver](
[Id] [int] NOT NULL,
[Receiver] [int] NOT NULL,
CONSTRAINT [PK_WarningReceiver_Id] PRIMARY KEY (Id)
 );

------

INSERT INTO WarningReceiver(Id, Type) VALUES (1, 'Mechanic');
INSERT INTO WarningReceiver(Id, Type) VALUES (2, 'Driver');

INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (1, 'Rear sensor', 2);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (2, 'Test sensor', 1);
INSERT INTO SensorType(Id, Type, DisplayWarningTo) VALUES (3, 'Production sensor', 2);

Я склонен не использовать столбцы идентификаторов для подобных вещей и указывать свой собственный идентификатор, который я сопоставляю непосредственно с константой C #, например

public enum SensorType
{
    RearSensor = 1,
    TestSensor = 2,
    ProductionSensor = 3
}

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

var engine_sensor = // get engine sensor from db.
if (engine_sensor == (int)SensorType.RearSensor)
{
   // do something
}
else if (engine_sensor == (int)SensorType.TestSensor)
{
   // display something to mechanic or whatever
}

Я действительно не знаю, что такое домен вашего приложения, так что извините, если это не имеет смысла.

Итак, подведу итоги и постараюсь ответитьваш вопрос;

  • Да, я действительно думаю, что вам лучше с FK's
  • Вы можете просто использовать их как столбцы int и определять датчики в коде, как я делал с enum
  • Я склонен делать и то и другое - определять перечисление для хорошей строгой типизации в коде и - создавать таблицу внешнего ключа для завершения моей схемы в базе данных.Это все еще стоит иметь по двум причинам;1) Когда вы пишете SQL-запросы в Management Studio или что-то в этом роде, и вы смотрите на свою таблицу engine_sensors и видите числа для типа датчика, вы можете присоединиться к вашей таблице FK, чтобы увидеть, какие датчики являются .Делает все немного проще

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

Надеюсь, это поможет.

1 голос
/ 21 июля 2010

Вы добавили один кусок информации

' Это база данных SQL Server, и я понимаю, что вы будете использовать битовое поле. Мне было интересно, насколько плоха идея заменить их внешними ключами на отдельную таблицу '

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

Но вы все еще не сказали , почему вам было интересно заменить их на ФК. Если вы скажете людям, какова ваша конечная цель или чего вы пытаетесь достичь, они с большей вероятностью предложат ряд решений.

Извините, я не могу предложить решение. Является ли внешний ключ (к чему?) Лучше, чем логическое значение? по сравнению с?

Я думаю, вам нужно немного уточнить / реструктурировать свой вопрос. Удачи.

0 голосов
/ 21 июля 2010

Использование 'bit' в SQL-сервере (0 или 1) автоматически отобразит логическое значение в linq to SQL, если вы все еще хотите использовать логическое значение в своем коде.

Но вы еще не указали, какая база данныхили почему вы хотите альтернативу bool.

0 голосов
/ 21 июля 2010

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

Однако, если вам нужно хранить очень разные логические значения, иногда более полезно использовать битовые маски старой школы, хранящиеся в INT,BIGINT или даже BINARY столбец.

...