检查连接字符串数据的SQL外键

检查连接字符串数据的SQL外键,sql,foreign-keys,Sql,Foreign Keys,我有一个表Shops和一个表ShopProducts和一个表ShopProducts和一个列Name Products列的要点是以逗号分隔的字符串列出商店销售的所有ShopProducts。我想验证上述列中的所有产品是否存在于表Shop products中。如果表ShopProducts中存在名为“Pizza”和“croissant”的记录,是否可能有一个外键来验证“Pizza,croissant”格式的数据是否有效?虽然将列表存储为字符串数据有一些有效的原因,但如果您需要引用完整性,则您的列表

我有一个表
Shops
和一个表
ShopProducts
和一个表
ShopProducts
和一个列
Name


Products
列的要点是以逗号分隔的字符串列出商店销售的所有
ShopProducts
。我想验证上述列中的所有产品是否存在于表
Shop products
中。如果表
ShopProducts
中存在名为“Pizza”和“croissant”的记录,是否可能有一个外键来验证“Pizza,croissant”格式的数据是否有效?

虽然将列表存储为字符串数据有一些有效的原因,但如果您需要引用完整性,则您的列表不属于此类情况。数据库已经有了一个功能,允许您存储和轻松查询列表,它们被称为表

因此,您不必在
Shop
表中使用逗号分隔的列表,而应该使用逗号分隔列表将每个项目存储为自己的行。通常情况下,您会得到一个类似以下内容的模式:

店铺(店铺ID(主键)、名称等)

产品(产品ID(主键)、名称等)

ShopProduct(ShopID(主键,副键),ProductID(主键,副键))

这允许您确保避免重复(如果您需要),并确保每个产品都是有效的

如果您在任何时候都需要逗号分隔的列表,您可以创建一个,尽管您的创建方式与DMBS非常相关,而且由于您没有指定一个,因此我不会列出所有选项,但
STRING\u AGG
是一种方法(如果您的DMBS支持):


虽然将列表存储为字符串数据有一些正当的理由,但如果您需要引用完整性,那么您的列表就不属于这种情况。数据库已经有了一个功能,允许您存储和轻松查询列表,它们被称为表

因此,您不必在
Shop
表中使用逗号分隔的列表,而应该使用逗号分隔列表将每个项目存储为自己的行。通常情况下,您会得到一个类似以下内容的模式:

店铺(店铺ID(主键)、名称等)

产品(产品ID(主键)、名称等)

ShopProduct(ShopID(主键,副键),ProductID(主键,副键))

这允许您确保避免重复(如果您需要),并确保每个产品都是有效的

如果您在任何时候都需要逗号分隔的列表,您可以创建一个,尽管您的创建方式与DMBS非常相关,而且由于您没有指定一个,因此我不会列出所有选项,但
STRING\u AGG
是一种方法(如果您的DMBS支持):


“逗号分隔字符串”-->断开的数据模型。修复你的数据模型。@GordonLinoff,为什么?如果我只需要它作为一个字符串来显示,不是吗?无论如何,你会建议我如何修复它(我有点好奇)。如果你“只是”需要作为一个字符串来显示,你就不需要外键了。@a_horse_没有名字,不正确,我想确保字符串的元素确实存在。那么你需要它们不仅仅是“只是显示”在这种情况下,您不应该将它们存储为逗号分隔的列表-这违反了良好数据库设计的最基本原则。“逗号分隔字符串”-->损坏的数据模型。修复你的数据模型。@GordonLinoff,为什么?如果我只需要它作为一个字符串来显示,不是吗?无论如何,你会建议我如何修复它(我有点好奇)。如果你“只是”需要作为一个字符串来显示,你就不需要外键了。@a_horse_没有名字,不正确,我想确保字符串的元素确实存在。那么你需要它们不仅仅是“只是显示”在这种情况下,您不应该将它们存储为逗号分隔的列表-这违反了良好数据库设计的最基本原则。唯一合理的解决方案是:谢谢,我不知道所有这些!:)这个问题唯一合理的解决办法谢谢,我不知道这一切!:)
SELECT  s.ShopID,
        s.Name AS ShopName,
        STRING_AGG(p.Name, ',') AS Products
FROM    Shop AS s
        INNER JOIN ShopProduct AS sp
            ON sp.ShopID = s.ShopID
        INNER JOIN Product AS p
            ON p.ProductID = sp.ProductID
GROUP By s.ShopID, s.Name;