如何定义来自不同来源的表之间的关系?

时间:2016-11-09 20:17:02

标签: sql sql-server sql-server-2008 relational-database

我需要对两个主要系统进行彻底检修。从BI角度出发,我创建了一些基线表,"用户"," CRM详细信息","电话详细信息"等

我在理解表之间如何形成关系方面存在问题。

我将一个用户列表放入"用户"表格,我需要在"电话细节"中做同样的事情。表。我如何建立一个知道约翰史密斯'来自用户='约翰史密斯'在电话?

我预计关键列将是" Id"在Users表中,因此" UserId"在Telephony表中,但UserId如何在Telephony表中结束?

我到目前为止的代码:

CREATE TABLE Users
(
    Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Forename  NVARCHAR(50),
    Surname   NVARCHAR(50),
    Location  CHAR(50),
    Email     NVARCHAR(320),
    SCD_Start SMALLDATETIME,
    SCD_Stop  SMALLDATETIME,
    IsActive  BIT
)

INSERT INTO Users (Forename,Surname,Location,SCD_Start,SCD_Stop,IsActive)
VALUES ('Test1','Test1','TestL1','2016-11-08',NULL,1)
,('Test2','Test2','TestL2','2016-11-08',NULL,1)
,('Test3','Test3','TestL3','2016-11-08',NULL,1)
,('Test4','Test4','TestL4','2016-11-08',NULL,1)
,('Test5','Test5','TestL5','2016-11-08',NULL,1)
,('Test6','Test6','TestL6','2016-11-08',NULL,1)

CREATE TABLE Telephony
(
    Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Forename    NVARCHAR(50),
    Surname     NVARCHAR(50),
    OfficePhone VARCHAR(22),
    MobilePhone VARCHAR(22),
    SCD_Start   SMALLDATETIME,
    SCD_Stop    SMALLDATETIME,
    IsActive    BIT
)

3 个答案:

答案 0 :(得分:0)

对于这种特殊情况,您需要在Telephony表中引入一个引用用户表中Id的外键。

CREATE TABLE Telephony
        (Id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
        UserId int FOREIGN KEY REFERENCES Users(Id)
        Forename    NVARCHAR(50),
        Surname     NVARCHAR(50),
        OfficePhone VARCHAR(22),
        MobilePhone VARCHAR(22),
        SCD_Start   SMALLDATETIME,
        SCD_Stop    SMALLDATETIME,
        IsActive    BIT
)

一般来说,如果你比设计数据库更熟悉设计软件,那么挖掘域建模和代码优先原则可能是一个好主意。

答案 1 :(得分:0)

基本上,只需在Telephony中添加另一列与用户ID中的类型(INT)相匹配 - 称之为UserId(通常我会在其前面加上“f”,fUserId只是如此快速一瞥让我想起了它FK而不是其他一些价值)。然后运行以下命令:

__index()

现在添加到Telephony 的任何记录必须具有匹配的UserId。使用“用户ID”值进行查询,您只能获得他们的数字。

就是这样。

答案 2 :(得分:0)

按名称识别

大概在两个表中都有

PRIMARY KEY (forename, surname);

您必须确定用户行中的名称何时表示与Telephony中某行相同的人员。也许是

Users.forename = Telephony.forename AND Users.surname = Telephony.forename

这是一个data cleansing/cleaning/scrubbing问题。无论如何,让我们说有条件...

表格表示关系。如果它是基础或元数据表,DBA /设计师会告诉您关系。如果它是查询的结果,则查询会告诉您关系。

因此,如果您有一个涉及两个表的查询,并且表中的行按名称引用人员,并且您希望由两行命名的人员引用相同的人员,那么您需要将需求...添加到查询。

添加ID

我们指定唯一ID来引用实体for many reasons。例如,因为你不想改变许多地方,当一个人改变他们的名字时,这个名字会出现。例如,这样您的查询只能涉及ids而不是多列的相等性。例如,通过使用较小的(整数)标识符而不是较大的(varchar)标识符,您可以减少实现空间(在表和索引中)和时间(在比较和索引中),但代价是增加实现空间(更多表)和时间(更多连接)。例如,您可以将多个名称与同一个人关联起来。请注意,任何设计决策都存在权衡。

假设您需要ID:首先按SQL Server: how to add new identity column and populate column with ids?为每个表添加一个id列“并创建并自动填充该列”。如果你从没有id的表开始:

ALTER TABLE Users ADD Id INT IDENTITY(1,1) PRIMARY KEY
ALTER TABLE Telephony ADD Id INT IDENTITY(1,1) PRIMARY KEY

然后根据Update a table using JOIN in SQL Server?将每个Telephony id设置为用户ID,每个“......”具有相同的名称:

UPDATE t
SET t.Id = u.Id
FROM Users as u
INNER JOIN Telephony as t
WHERE ...

现在您不需要或想要电话中的名字:

DROP FORENAME, SURNAME FROM Telephony

声明外键

“关系”(表之间)也用于“外键约束”。您需要从电话到用户的FK。你可能想要ID。但是查询不需要约束。 (元数据具有关系表“从表TF列列表LF到表TT列列表LT有fk”,也可通过“表TF列列表LF的值列表表示为表TT列列表的值列表” LT“。)inal Telephony,

FOREIGN KEY (forename, surname) REFERENCES Users (forename, surname);

对于新表,

FOREIGN KEY (Id) REFERENCES Users (Id)

<强> PS

约束实际上不是关系,它是元数据关系的实例,即参与该元数据关系的某些值的一种情况。它声明了关于基表中值的事实。但同时,因为每个基表都包含满足某种应用程序关系的行,所以它根据它提到的基表的应用程序关系来说明每个应用程序情况的事实。当表T表示以E_T表示的关系时,FK约束tf (c) REFERENCES tt (c)表示“对于所有其他列的某些值,E_tf表示E_tt”。