这是 SQL 的核心部分。在适当的关系设计中,您不会将电子邮件地址与人员、组或资源相关联——您将人员、组和资源与电子邮件相关联。
所以,有一个电子邮件表:
CREATE TABLE dbo.tblEmail (
emailID int IDENTITY PRIMARY KEY,
email varchar(500)
)
如果您只需要每个实体一封电子邮件,您只需在其他每个字段中插入一个emailID,以模拟可能需要电子邮件的内容。
ALTER TABLE dbo.tblPerson
ADD emailID int REFERENCES dbo.tblEmail(emailID);
ALTER TABLE dbo.tblGroup
ADD emailID int REFERENCES dbo.tblEmail(emailID);
ALTER TABLE dbo.tblResource
ADD emailID int REFERENCES dbo.tblEmail(emailID);
如果您需要每个实体多个 电子邮件地址,您需要插入一个附加表,以将一组电子邮件地址插入到特定地址。 (我不会这样做,除非您有单独处理地址的技术原因,例如批量电子邮件系统,如果有人将同一电子邮件用于自己和组织的使用,您希望在该系统中避免重复。)
CREATE TABLE dbo.tblEmail (
emailID int IDENTITY PRIMARY KEY
)
CREATE TABLE dbo.tblEmailAddress (
eAddrID IDENTITY PRIMARY KEY,
eAddr varchar(500)
)
CREATE TABLE dbo.tblEmailSet (
emailID int REFERENCES dbo.tblEmail(emailID),
eAddrID int REFERENCES dbo.tblEmailAddresses(eAddrID),
)
例如,为了将所有电子邮件列表返回给名为“Smith”的任何个人、组或资源,您需要运行以下查询:
SELECT DISTINCT A.eAddr
FROM (
SELECT emailID FROM dbo.tblPerson WHERE Name = 'Smith'
UNION
SELECT emailID FROM dbo.tblGroup WHERE Name = 'Smith'
UNION
SELECT emailID FROM dbo.tblResource WHERE Name = 'Smith'
) AS PGR
INNER JOIN dbo.tblEmailSet AS S
ON PGR.emailID = S.emailID
INNER JOIN dbo.tblEmailAddress AS A
ON S.eAddrID = A.eAddrID
那个丑陋的UNION,顺便说一句,是你真的不想这样做的原因之一,除非你有技术需要来唯一地检索数据。虽然我有时会执行这种多对多对多的连接,但在这种特殊情况下,它有点像“代码味道”,并且是一个指示符,而不是跟踪“人”、“组”和“资源”,您应该使用“类型”指示器跟踪“联系人”,以判断联系人是人员、组还是资源。
(或者也许您永远不需要获取一堆电子邮件地址,而只需要一个可以检查白名单的电子邮件表......)