【问题标题】:Inserting data with foreign keys and avoiding duplication使用外键插入数据并避免重复
【发布时间】:2014-06-28 07:02:02
【问题描述】:

我是 MySQL 的初学者,刚刚开始使用外键和 INNER JOIN 运算符。 所以我制作了一些表格,例如:

CREATE TABLE `models` 
(
`id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT, 
`name` VARCHAR (255) NOT NULL, 
`price` MEDIUMINT UNSIGNED NOT NULL,
PRIMARY KEY( `id` )
);

CREATE TABLE `vendors` 
(
`id` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,  
`name` VARCHAR (255) NOT NULL,
`id_model` TINYINT UNSIGNED NOT NULL,
PRIMARY KEY( `id` ),
FOREIGN KEY (`id_model`) REFERENCES models(`id`)
);

CREATE TABLE `cars` 
(
`serial_number` MEDIUMINT UNSIGNED NOT NULL,  
`id_vendor` TINYINT UNSIGNED NOT NULL,
FOREIGN KEY (`id_vendor`) REFERENCES vendors(`id`),
PRIMARY KEY( `serial_number` )
);

我知道如何获得输出。但是,问题是我不知道如何正确插入数据。我所能做的就是逐表插入数据。但是如何在一个查询中做到这一点,如果我插入本田思域并且已经有本田雅阁,例如,它不会在数据库中重复本田供应商吗?

【问题讨论】:

    标签: mysql sql foreign-keys


    【解决方案1】:

    似乎数据库的结构不是很连贯。也许我不明白你在做什么,但是……不管怎样,就这样吧。

    假设您要做的是将汽车列表存储在正确的normalized relational database, 中,您要做的第一件事就是思考“现实生活”中正在发生的事情:

    • 制造商(供应商)制造/销售汽车
    • 制造商(供应商)生产不同型号的汽车
    • 汽车有型号(在您的情况下还有序列号)
    • 模型属于供应商(制造商)

    考虑到这一点,您的表结构是:

    Vendors
    - id
    - name
    
    Models
     - id
     - name
     - vendor ( foreign key => vendor.id )
    
    Cars    
    - id
    - serial_number
    - model ( foreign key => model.id )
    

    您不需要在汽车表中引用供应商,因为您引用了模型,而模型又引用了供应商。

    插入时,一个一个进行,确保外键条目已经存在。

    • 在插入汽车对象时,只需提供模型 ID。
    • 插入模型对象时,您需要提供供应商 ID。

    因此,本田思域/雅阁的情况不会重复本田。表格应该是这样的:

    Vendor
    
    id, name
    1, "Honda" 
    
    Model
    
    id, name, vendor
    1, "Civic", 1
    2, "Accord", 1
    
    Cars
    
    id, serial_no, model
    1, "A serial", 2 -> a honda accord
    2, "Another serial", 1 -> a honda civic
    

    希望这会有所帮助。

    【讨论】:

    • 是的,我想我的例子不太对,谢谢。你的认识似乎更好。但我想知道如何解决这个问题。感谢您的回复。
    【解决方案2】:

    您需要自己检查是否存在重复记录。

    IF EXISTS (SELECT * FROM vendors WHERE Name = 'Honda')
    BEGIN
        -- Insert into cars with existing vendor id
    END
    ELSE
    BEGIN
        IF EXISTIS (SELECT * FROM models WHERE Name = 'your model name')
        BEGIN
            -- insert into vendors with existing model id
        END
        ELSE
        BEGIN
            -- insert into models
            -- insert into vendors
            -- insert into cars
        END
    END
    

    您可以为其创建存储过程,并将汽车、供应商和型号作为参数传递。 或者你可以先列出模型,插入它们;然后是所有供应商和所有汽车。只是一个愚蠢的答案。欢迎使用更复杂的解决方案。

    【讨论】:

    • 是的,我想这是唯一的解决方案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多