Webcodeexpert.com Ответов: 3

Сомнение в соотношении 1-1 в таблице


I just want to clear doubts about 1 to 1 relationship in sql. To understand i have created following example. 

Please let me know is this the correct way to implement(1:1) relationship or not. 


Что я уже пробовал:

CREATE TABLE tbEmployee (
     EmployeeId  INT IDENTITY(1,1) PRIMARY KEY NOT NULL ,
     EmployeeName  VARCHAR(100)
);


GO
CREATE TABLE tbEmployeeIdentityDetails (
    RecordId INT IDENTITY(1,1) PRIMARY KEY NOT NULL ,
 	AadharNumber VARCHAR(20) NOT NULL,
	EmployeeId INT UNIQUE FOREIGN KEY REFERENCES tbEmployee(EmployeeId)
);


GO
	INSERT INTO tbEmployee (EmployeeName)   
	VALUES
    ('Aman'),
    ('Kapil'),
    ('Vijay'),
    ('Panjak');

GO
INSERT INTO tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
VALUES
('3157 8787	0987', 1),
('6432 3246	9097', 2),
('8875 8746	9234', 3),
('4678 4526	6654', 4);


GO
SELECT * FROM tbEmployee
SELECT * FROM tbEmployeeIdentityDetails


--On trying to insert another record for the same employee generates error e.g.

INSERT INTO tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
VALUES
('3157 8787 0987',4);

Исключения: нарушение ограничения уникального ключа 'UQ__tbEmploy__7AD04F10917285FA'. Не удается вставить дубликат ключа в объект 'dbo.tbEmployeeIdentityDetails'. Повторяющееся значение ключа: (4).
Заявление было прекращено.

Он допускает только одну запись для каждого сотрудника в таблице tbEmployeeIdentityDetails, которая является правильной. Но я думаю, что это должно следовать концепции: Один номер aadhar может принадлежать только одному сотруднику 1, а 1 сотрудник может иметь только один номер aadhar, поскольку номер aadhar является уникальным идентификатором для каждого сотрудника в Индии

3 Ответов

Рейтинг:
2

Maciej Los

Я полностью согласен с О. Г. и хотел бы указать вам на эту статью: Один-к-одному (модель данных) - Википедия[^], который подробно объясняет отношения один-к-одному:

Цитата:
Важно отметить, что отношение "один к одному" является не свойством данных, а скорее самим отношением. Список матерей и их детей может описывать матерей только с одним ребенком, и в этом случае одна строка таблицы матерей будет ссылаться только на одну строку таблицы детей и наоборот, но сама связь это не один к одному, ...


Рейтинг:
0

OriginalGriff

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


Maciej Los

5ed!

Webcodeexpert.com

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

OriginalGriff

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

Webcodeexpert.com

На самом деле я следил за этими 3 статьями
https://www.tech-recipes.com/rx/56738/one-to-one-one-to-many-table-relationships-in-sql-server/

https://code.tutsplus.com/articles/sql-for-beginners-part-3-database-relationships--net-8561

https://howtoprogramwithjava.com/database-relationships-many-many-one-one/

но не смог получить правильный путь и использовать отношения 1-к-1. Пожалуйста, предложите, какой из них я должен следовать..

Webcodeexpert.com

спасибо за ваши комментарии. Я переработал таблицу, и она работает так, как требуется. Пожалуйста, посмотрите и дайте мне знать, правильно это или нет

идти
Создать таблицу tbEmployee (
EmployeeId INT IDENTITY(1,1) первичный ключ NOT NULL ,
Имя сотрудника VARCHAR(100)
);


ГО
Создать таблицу tbEmployeeIdentityDetails (
EmployeeId INT PRIMARY KEY FOREIGN KEY REFERENCES tbEmployee(EmployeeId),
AadharNumber VARCHAR(20) NOT NULL,
Ограничение UC_Employee_AadharNumber UNIQUE (AadharNumber)
);


ГО
Вставить в tbEmployee (EmployeeName)
ЦЕННОСТИ
("Аман"),
("Капил"),
("Виджай"),
("Панджак");

ГО
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('3157 8787 0987', 1),
('6432 3246 9097', 2),
('8875 8746 9234', 3)


ГО
Выберите * из списка tbEmployee
Выберите * из списка tbEmployeeIdentityDetails



если мы попытаемся вставить идентификационные данные для того же EmployeeId, который уже существует в таблице tbEmployeeIdentityDetails, он покажет ошибку "нарушение ограничения первичного ключа".

Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('5543 4532 1123',2);


если мы попытаемся вставить идентификационные данные для идентификатора an EmployeeId который не существует в таблице tbEmployee это приведет к ошибке нарушения внешнего ключа
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('8157 8789 4987',9);


если мы попытаемся вставить существующий номер aadhar для EmployeeId, он покажет ошибку "нарушение ограничения уникального ключа"
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('3157 8787 0987',4);

Рейтинг:
0

MadMyche

Сначала о главном. Как заявил ОГ (Оригинал Грифф), AadharNumber к нему нужно было бы применить уникальный индекс. Если он будет храниться в Идентификационные Данные Сотрудника таблица, то вы можете запустить этот код:

CREATE UNIQUE NONCLUSTERED INDEX [IX_EmployeeIdentity_AadharNumber]
ON dbo.tbEmployeeIdentityDetails ( AadharNumber)
GO


Во-вторых, как спросил ОГ, почему они находятся в разных таблицах? Единственная реальная причина для разделения информации - это если размер строки превышает 8 КБ или если объем данных вызывает проблемы с производительностью. Отрицательными сторонами этой конструкции являются накладные расходы, связанные с наличием дополнительной таблицы, влияние на производительность ограничения внешнего ключа (которое по существу должно выполнять выбор в первой таблице), а также запросы, необходимые для получения всех данных. Еще одна вещь об ограничении FK - если вы не выполняете сложные звездообразные запросы, они практически не приносят никакой пользы, когда речь заходит о производительности.

Что касается таблицы сотрудников... если вы не собираетесь добавлять к нему Аадхар, ему потребуется больше уникальной информации. Некоторые имена довольно распространены, и столкновение вполне вероятно.

Теперь, для простого тестирования и обучения, мы оставим все как есть и предположим, что когда вы действительно создадите что-то реальное, вы будете следовать приведенным выше предложениям.

И мои предложения.
Я вообще не рекомендую использовать "прямой" доступ к таблицам (например, Insert, Select, Edit, Delete) и предпочитаю использовать хранимые процедуры. С двумя запросами вставки, которые у вас были, я заметил, что вы не всегда гарантируете, что второй набор идентификаторов, опубликованных, будет соответствовать первому. Если бы это было сделано с помощью программы, это исключило бы круговые поездки между приложением и базой данных с помощью этого, и вы даже могли бы вернуть новый идентификатор сотрудника следующим образом:
CREATE PROCEDURE dbo.EmployeeAndDetails_Create (
	@Name NVARCHAR(32),
	@Aadhar NVARCHAR(14)
 ) AS 
BEGIN
	SET NOCOUNT ON

	DECLARE @EmpID INT = -1

	INSERT tbEmployee (EmployeeName)
	VALUES (@Name)

	SET @EmpID = Scope_Identity()

	INSERT tbEmployeeIdentityDetails (EmployeeId, AadharNumber)
	VALUES (@EmpID, @Aadhar)

	SELECT NewEmployeeID = @EmpID
END
GO


Webcodeexpert.com

спасибо за ваш ответ..На самом деле я следил за этими 3 статьями
https://www.tech-recipes.com/rx/56738/one-to-one-one-to-many-table-relationships-in-sql-server/

https://code.tutsplus.com/articles/sql-for-beginners-part-3-database-relationships--net-8561

https://howtoprogramwithjava.com/database-relationships-many-many-one-one/

но не смог получить правильный путь и использовать отношения 1-к-1. Пожалуйста, предложите, какой из них я должен следовать..

MadMyche

Как программировать с Javas, кажется, лучше всего до сих пор; но я не прошел через всю серию

Webcodeexpert.com

спасибо за ваши комментарии. Я переработал таблицу, и она работает так, как требуется. Пожалуйста, посмотрите и дайте мне знать, правильно это или нет

идти
Создать таблицу tbEmployee (
EmployeeId INT IDENTITY(1,1) первичный ключ NOT NULL ,
Имя сотрудника VARCHAR(100)
);


ГО
Создать таблицу tbEmployeeIdentityDetails (
EmployeeId INT PRIMARY KEY FOREIGN KEY REFERENCES tbEmployee(EmployeeId),
AadharNumber VARCHAR(20) NOT NULL,
Ограничение UC_Employee_AadharNumber UNIQUE (AadharNumber)
);


ГО
Вставить в tbEmployee (EmployeeName)
ЦЕННОСТИ
("Аман"),
("Капил"),
("Виджай"),
("Панджак");

ГО
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('3157 8787 0987', 1),
('6432 3246 9097', 2),
('8875 8746 9234', 3)


ГО
Выберите * из списка tbEmployee
Выберите * из списка tbEmployeeIdentityDetails



если мы попытаемся вставить идентификационные данные для того же EmployeeId, который уже существует в таблице tbEmployeeIdentityDetails, он покажет ошибку "нарушение ограничения первичного ключа".

Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('5543 4532 1123',2);


если мы попытаемся вставить идентификационные данные для идентификатора an EmployeeId который не существует в таблице tbEmployee это приведет к ошибке нарушения внешнего ключа
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('8157 8789 4987',9);


если мы попытаемся вставить существующий номер aadhar для EmployeeId, он покажет ошибку "нарушение ограничения уникального ключа"
Вставить в tbEmployeeIdentityDetails (AadharNumber, EmployeeId)
ЦЕННОСТИ
('3157 8787 0987',4);

Webcodeexpert.com

.