Определение отношения один-к-одному в SQL Server

Мне нужно определить отношение один к одному, и я не могу найти правильный способ сделать это в SQL Server.

Почему отношения один к одному вы спрашиваете?

Я использую WCF в качестве DAL (Linq) и у меня есть таблица, содержащая столбец BLOB. BLOB вряд ли когда-либо изменится, и это будет пустой тратой пропускной способности для передачи его при каждом запросе.

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

Есть идеи?

6 ответов

Решение

Фактически один-к-одному часто используют в отношениях супертип / подтип. В дочерней таблице первичный ключ также служит внешним ключом для родительской таблицы. Вот пример:

org_model_00

CREATE TABLE Organization
( 
     ID       int PRIMARY KEY,
     Name     varchar(200),
     Address  varchar(200),
     Phone    varchar(12)
)
GO

CREATE TABLE Customer
( 
     ID              int PRIMARY KEY,
     AccountManager  varchar(100)
)
GO

ALTER TABLE Customer
    ADD  FOREIGN KEY (ID) REFERENCES Organization(ID)
        ON DELETE CASCADE
        ON UPDATE CASCADE
GO

Почему бы не сделать внешний ключ каждой таблицы уникальным?

Нет такой вещи как явное отношение один к одному.

Но из-за того, что tbl1.id и tbl2.id являются первичными ключами, а tbl2.id является внешним ключом, ссылающимся на tbl1.id, вы создали неявное отношение 1:0..1.

Поместите 1:1 связанных предметов в одну строку в той же таблице. Отсюда и происходит "отношение" в "реляционной базе данных" - связанные вещи попадают в одну строку.

Если вы хотите уменьшить размер данных, передаваемых по проводам, рассмотрите возможность проецирования только нужных столбцов:

SELECT c1, c2, c3 FROM t1

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

CREATE VIEW V1 AS SELECT c1, c2, c3 FROM t1
SELECT * FROM t1
UPDATE v1 SET c1=5 WHERE c2=7

Обратите внимание, что большие двоичные объекты хранятся в автономном режиме в SQL Server, поэтому вы не экономите много дискового ввода-вывода путем вертикального разделения данных. Если бы это были столбцы, отличные от BLOB, вы можете использовать вертикальное разбиение, как вы описали, потому что вы будете выполнять меньше операций дискового ввода-вывода для сканирования базовой таблицы.

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

Затем вы можете создать объект EF на основе представления.

Как насчет этого. Свяжите первичный ключ в первой таблице с первичным ключом во второй таблице.

Tab1.ID (PK) <-> Tab2.ID (PK)

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

Другие вопросы по тегам