我有一张桌子人物:
Id Name
1 Person1
2 Person2
3 Person3
我有它的子表简介:
Id PersonId FieldName Value
1 1 Firstname Alex
2 1 Lastname Balmer
3 1 Email some_email@test.com
4 1 Phone +1 2 30004000
我想从这两个表中获取数据,如下所示:
Id Name Firstname Lastname Email Phone
1 Person1 Alex Balmer some_email@test.com +1 2 30004000
我想在我的数据库层(C#)中使用强类型并使用LINQ(编程时),这意味着当我在Profile表中添加一些新的Key,Value对时,我想在DB和C#中进行最小的修改如果可能的话。实际上,我正试图在这种情况下获得一些最佳实践。
答案 0 :(得分:1)
Select
P.ID
, P.Name
, Case When C.FieldName = 'FirstName' Then C.Value Else NULL END AS FirstName
, Case When C.FieldName = 'LastName' Then C.Value Else NULL END AS LastName
, Case When C.FieldName = 'Email' Then C.Value Else NULL END AS Email
, Case When C.FieldName = 'Phone' Then C.Value Else NULL END AS Phone
From Person AS P
Inner JOIN Child AS C
ON P.ID = C.PersonID
你可以使用PIVOT;不确定哪一个最容易添加新列。
答案 1 :(得分:1)
使用强类型字段的最佳优化方法是这样做:
CREATE TABLE Persons
(PersonID int identity(1,1) primary key
,Firstname varchar(...)
,Lastname varchar(...)
,Email varchar(...)
,Phone varchar(...)
,....
)
然后最优化的查询将是:
SELECT
PersonID,Firstname,Lastname,Email,Phone
FROM Persons
WHERE ...
将所有主列添加到人员表中。如果您需要专门创建其他表:
--one person can play many instruments with this table
CREATE TABLE PersonMusicians
(PersonID int --pk fk to Persons.PersonID
,InstrumentCode char(1) --pk
,...
)
--only one row per person with this table
CREATE TABLE PersonTeachers
(PersonID int --pk fk to Persons.PersonID
,FavoriteSubjectCode char(1)
,SchoolName varchar(...)
)
如果你必须有无限的动态属性字段,那么我会尽可能完全地创建上面的结构(尽可能多的常见字段)然后有一个“AdditionalInfo”表,你可以存储所有的信息,如:
AdditionalInfoFields
FieldID int identity(1,1) primary key
FieldName varchar(...)
AdditionalInfo
AdditionalInfoID int identity(1,1) primary key
PersonID int fk to Persons.PersonID
FieldID int fk to AdditionalInfoFields.FieldID
FieldValue varchar(..) or you can look into sql_variant
在AdditionalInfo.PersonID+FieldID
上有一个索引,如果你要搜索所有拥有属性X的人,那么还有另一个像AdditionalInfo.FieldID+PersonID
如果没有上述任何一项,您将需要使用您在选项#1中提到的四个左外连接:
SELECT
P.ID, p.Name
, p1.Value AS Firstname
, p2.value AS Lastname
, p3.Value AS Email
, p4.Value AS Phone
FROM Persons p
LEFT OUTER JOIN Profile p1 ON p.PersonID=p1.PersonID AND p1.FieldName='Firstname'
LEFT OUTER JOIN Profile p1 ON p.PersonID=p1.PersonID AND p1.FieldName='Lastname'
LEFT OUTER JOIN Profile p1 ON p.PersonID=p1.PersonID AND p1.FieldName='Email'
LEFT OUTER JOIN Profile p1 ON p.PersonID=p1.PersonID AND p1.FieldName='Phone'
WHERE ....
你总是可以使用这个左连接查询中的索引创建一个物化视图,并为你预先计算数据,这样可以加快它的速度。