0

我有一个问题,我们有一个客户表,其中包括姓名、电子邮件、地址和一个技能表,它是 qts,由一个 id 关联的急救。例如

Customer
id = 1
Name = James
Address =  some address

Skills
1, qts
2, first aid

我现在正在尝试配对这种关系。我首先通过创建一个只有 customerId 的技能表来快速解决问题,并且每个技能都有一个真/假值。然后在 customer_skills 与 customerId 到 SkillId 之间创建一个跳转。但是当值发生变化时,我不知道如何更新记录,因为没有唯一的 id。

任何人都可以帮助解决此问题的最佳方法吗?

谢谢....

4

2 回答 2

3

您想要的解决方案实际上取决于您的数据,并且这个问题之前已经被问过数千次。如果你用谷歌搜索 实体属性值与严格的关系模型,你会看到无数文章比较和对比了可用的方法。


严格关系模型

您将为每个技能添加额外的BITDATETIME字段(其中NULL日期时间表示客户不具备该技能)到您的客户表中。如果您的技能很少随着时间的推移不太可能发生很大变化,那么这很有效。这允许简单的查询来定位具有技能的客户,尤其是具有各种技能组合的客户,例如(使用日期时间字段)

SELECT  *
FROM    Customer
WHERE   Skill1 >= '20120101' -- SKILL 1 AQUIRED AFTER 1ST JAN 2012
AND     Skill2 IS NOT NULL  -- HAS SKILL 2
AND     Skill2 IS NULL      -- DOES NOT POSSESS SKILL 3

实体-属性-值模型

这是对经典实体-属性-值模型的轻微改编,因为该值是由记录的存在表示的布尔值。您将创建一个像这样的表:

CREATE TABLE CustomerSkills
(       CustomerID      INT NOT NULL,
        SkillID         INT NOT NULL
    PRIMARY KEY (CustomerID, SkillID),
    FOREIGN KEY (CustomerID) REFERENCES Customer (ID),
    FOREIGN KEY (SkillID) REFERENCES Skills (ID)
)

您可能希望添加 DateAdded、AddedBy 等其他列来跟踪添加技能的时间和添加者等,但可以从上面收集核心原则。使用这种方法,添加技能要容易得多,因为它不需要添加列,但可以使简单的查询变得更加复杂。上面的查询必须写成:

SELECT  Customer.*
FROM    Customer
        INNER JOIN
        (   SELECT  CustomerID
            FROM    CustomerSkills
            WHERE   SkillID IN (2, 3)   -- SKILL2,SKILL3
            OR      (SkillID = 1 AND DateAdded >= '20120101')
            GROUP BY CustomerID 
            HAVING  COUNT(*) = 2
            AND     COUNT(CASE WHEN SkillID = 3 THEN 1 END) = 0
        ) skills
            ON Skills.CustomerID = Customer.ID

与关系模型相比,这更加复杂且资源密集,但整体结构更加灵活。


总而言之,这真的取决于你自己的具体情况,有几个因素需要考虑,但有很多资源可以帮助你做出决定。

于 2012-06-08T09:45:32.850 回答
0

如果您有一个表将其他两个表的主键链接在一起以形成多对多关系(例如在您的示例中),则不必更新该表。相反,您可以删除并将值重新插入其中。

如果您正在编辑客户(例如 customerId 46)并更改该客户的技能,您可以删除该客户的所有技能,然后在存储更改时重新插入新的技能集。

如果您的“链接表”除了两个主键列之外还包含一些附加信息,那么情况可能会有所不同。但是根据您的描述,您似乎只想使用每个表中的主键将表链接在一起。在这种情况下,删除+重新插入应该没问题。

同样在这种表中,您应该使两个外键字段的组合成为绑定表的主键。

于 2012-06-08T09:02:17.583 回答