ber*_*hos 1 sql t-sql database multivalue
我发现自己的Person表中的一些属性需要保存多个值/选项,这不是一个好的SQL实践,所以我创建了第二个表,如下所示:
之前:
Person table
-ID (ex. 101)
-Name (ex. John)
-Accessories (ex. Scarf, Mask, Headband, etc..) - One person can have a combination of this
Run Code Online (Sandbox Code Playgroud)
后:
Person Table
-ID
-Name
PersonDetails Table
-PersonID (FK to Person table)
-Attribute type
-Attribute value
Run Code Online (Sandbox Code Playgroud)
一个例子:
Person:
ID:13; Name: John Snow
PersonDetails:
PersonID: 13; Attribute type: Accessories; Attribute value: Scarf
PersonID: 13; Attribute type: Accessories; Attribute value: Mask
Run Code Online (Sandbox Code Playgroud)
你可以看到ID为13的人有围巾和面具.
这是一个好习惯吗?还有哪些方法可以最有效地完成这项工作?
此外,如果有更新,13人没有围巾和面具但只有眼镜?(分别删除2并插入一个新的?这意味着只有一个修改请求的3个查询)
我认为这与n:m相关.您需要一张包含PersonID,姓名和其他人详细信息的表格.另一张Accessory带有ID,名称和更多配件细节的表格.第三个表PersonAccessory存储PersonID和AccessoryID对(这称为映射表)
CREATE TABLE Person(ID INT IDENTITY PRIMARY KEY,Name VARCHAR(100));
INSERT INTO Person VALUES('John'),('Jim');
CREATE TABLE Accessory(ID INT IDENTITY PRIMARY KEY,Name VARCHAR(100));
INSERT INTO Accessory VALUES('Scarf'),('Mask');
CREATE TABLE PersonAccessory(PersonID INT NOT NULL FOREIGN KEY REFERENCES Person(ID)
,AccessoryID INT NOT NULL FOREIGN KEY REFERENCES Accessory(ID));
INSERT INTO PersonAccessory VALUES(1,1),(2,1),(2,2);
SELECT p.Name
,a.Name
FROM PersonAccessory AS pa
INNER JOIN Person AS p ON pa.PersonID=p.ID
INNER JOIN Accessory AS a ON pa.AccessoryID=a.ID;
GO
--DROP TABLE PersonAccessory;
--DROP TABLE Accessory;
--DROP TABLE Person
Run Code Online (Sandbox Code Playgroud)
结果
John Scarf
Jim Scarf
Jim Mask
Run Code Online (Sandbox Code Playgroud)