SQL数据库设计外键

时间:2016-01-03 16:20:02

标签: jquery mysql database-design

你好,我对数据库很新,并且有设计问题/问题。

我有一个名为products的表,其中包含以下列,并存储有关产品的信息以及文章的三张相对较大的图片。

id = primary key
product_id = int
product_name = varchar
product_description = text 
image1_name = varchar
image1_data = longblob
image2_name = varchar
image2_data = longblob
image3_name = varchar
image3_data = longblob

我的网站上还有一个jquery动画幻灯片元素,它应该显示五张图片,我作为网站管理员可以选择并显示产品名称。

为此,我考虑创建第二个表幻灯片,其中包含不超过五个条目,并且基本上指向imagedata1,imagedata2或imagedata3以及产品的product_name

id = primary key
product_name = product.product_name
imagedata = imagedata 1 or 2 or 3

据我所知,SQL中没有指针。这怎么可以实现?我必须改变我的设计吗?

4 个答案:

答案 0 :(得分:0)

我最初的想法是你会有两张桌子。

-- product table --
id = primary key
product_id = int
product_name = varchar
product_description = text 

-- product_image_table --
id = primary key
product_table_id = {product table id}
image_name = varchar
image_data = longblob

然后在您正在考虑的新表上将引用product_image_table和可能的product表中的记录。与此相关的好处是您不限制在产品表上可以存储多少图像,如果您需要存储更多图像,则不必添加更多列,并且您不需要为产品添加空单元格小于你的最大图像数。

答案 1 :(得分:0)

这种情况可以有两种方法。

  1. 1nF的
  2. 3nf或BCNF
  3. 1NF:

    与您的一张桌子相同: 只需添加一列说明产品的滑块数。 您的imagename有5列。 如果要将图像存储在数据库中,则再使用blob数据类型

    再添加5个列

    3 NF:

    第一张包含产品详情的表

    [
        {
            "Name": "Or Benvenisti",
            "Status": "Online"
        },
        {
            "Name": "Liat Leibel",
            "Status": "Online"
        },
        {
            "Name": "Noy Lashon",
            "Status": "Offline"
        },
        {
            "Name": "Einav Chazen",
            "Status": "Online"
        },
        {
            "Name": "Tal Tolaat",
            "Status": "Offline"
        }
    ]
    

    带有图像信息的第二张表

     product_id = int (primary key)
     product_name = varchar
     product_description = text 
    

    我更喜欢将图像保存为文件格式并存储完整的URL以加载到数据库中。 如果您还想通过URL加载它,那么您可以删除imagedata列

    3NF或BCNF形式更为优先

答案 2 :(得分:0)

让我们考虑一下,目前您在产品的幻灯片放映中需要3张图片,但是,明天您可能需要1张或者您可能需要5张特定产品,所以很明显您的设计并非如此。足够灵活或过于灵活。

那么......这里的模型是什么?

One-To-many

这将为您提供最灵活的无任何冗余列

将其视为有很多图像的产品,您将如何对其进行建模?

您当前的产品表将不知道图片,并且您将添加一个名为product_images的新表

product_images
id | int
product_id | int
image_url | varchar

因此,如果您有产品,则可以对其进行另一次查询

SELECT * FROM product_images WHERE product_id = ?

或接收某些产品的所有图像

SELECT * FROM product_images WHERE product_id IN (?)

额外:假设您有许多需要图像功能的模型,您可以创建名为polymorphic table的{​​{1}},这个表不仅包含reference_id ,但是一个额外的列也有一个reference_type

images

现在,如果你有一个产品,你可以查询它的图像

images
id | int
reference_id | int
reference_type | varchar
image_url | varchar

或接收某些产品的所有图像

SELECT * FROM product_images WHERE reference_id = ? and reference_type = 'product'

当然,您可以根据需要查询其他reference_type。

答案 3 :(得分:0)

几乎无一例外,你想要正确地规范化设计。规范化的目的是最小化异常数据进入数据库。例如,您希望无法插入仅允许三个行的第四行。在行定义中创建三对列也可以实现这一点,但代价是额外的未使用空间和对未来增强的严格限制。

关系基数一直存在局限性。我们可以原生地定义1对多关系(实际上:1到0或更多),但我们不能原生地定义1对3的关系(1到0或更多,最多3个)。

因此,当我们必须在本机关系定义之外实现一个功能时,我们会做我们一直做的事情:我们作弊。

当然,有许多方法可以欺骗每个人,当然,每个人都有利弊。我最喜欢的是继续创建一个1米的桌子,并附加一些额外的约束:

create table ProductImages(
    ProdID   int not null,
    Card     tinyint not null,
    Name     varchar not null,
    Image    longblob not null,
    constraint PK_ProductImages primary key( ProdID, Card ),
    constraint CK_CardRange check( Card between 1 and 3 ),
    constraint FK_ProdImageProd foreign key( ProdID )
        references Products( ID )
);

这里的专业人士是你得到你想要的东西,即与任何特定产品相关的零,1,2或3个图像。

缺点是

  • 您必须以编程方式确定基数值:1,2或3.这不能自动生成。
  • 基数值必须介于1和3之间,但它们可以按任何顺序插入,也可能缺少值。

一方面,这些很容易在应用程序代码中处理。而且你保留了规范化的所有好处。

相关问题