Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL主键斗争_Sql_Oracle - Fatal编程技术网

SQL主键斗争

SQL主键斗争,sql,oracle,Sql,Oracle,我正在尝试为供应商组创建一个表,当我尝试创建它时,它会抛出一个错误 代码如下: CREATE TABLE GROUPS_PLUS_SUPPLIERS ( PRODUCT_GROUP_SUPPLIER_ID NUMBER(3), GROUP_ID NUMBER(4), GROUP_NAME VARCHAR2(255), SUPPLIER_ID NUMBER(4), CONSTRAINT PRODUCT_GROUP_SUPPLIER

我正在尝试为供应商组创建一个表,当我尝试创建它时,它会抛出一个错误

代码如下:

CREATE TABLE GROUPS_PLUS_SUPPLIERS  
(
    PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
    GROUP_ID NUMBER(4),    
    GROUP_NAME VARCHAR2(255),   
    SUPPLIER_ID NUMBER(4),    

    CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),   
    CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
);

CREATE TABLE PRODUCTS
(
    PRODUCT_ID NUMBER (4),
    PRODUCT_DESCRIPTION VARCHAR2 (255),
    PRODUCT_SIZE VARCHAR2 (10),
    PRODUCT_GROUP NUMBER (4),
    PRODUCT_PRICE NUMBER(4),
    NO_IN_STOCK NUMBER (4),
    REORDER_LEVEL NUMBER (4),

    CONSTRAINT PRODUCTS_ID_PK PRIMARY KEY (PRODUCT_ID),
    CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUPS_PLUS_SUPPLIERS(GROUP_ID)
);
这是我收到的错误消息:

ORA-02270:此列列表没有匹配的唯一键或主键

以下是我试图在group plus供应商中添加的内容:

INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (1,705,'flavoured oil',5588);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (2,705,'flavoured oil',5509);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (3,800,'spice',5543);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (4,800,'spice',5579);
INSERT INTO GROUPS_PLUS_SUPPLIERS VALUES (5,800,'spice',5584);

任何帮助都将不胜感激

错误消息会显示您缺少的内容。
GROUPS\u PLUS\u SUPPLIERS(GROUP\u ID)
的外键意味着您需要在此列上添加唯一索引

CREATE TABLE GROUPS_PLUS_SUPPLIERS  
(
    PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
    GROUP_ID NUMBER(4),    
    GROUP_NAME VARCHAR2(255),   
    SUPPLIER_ID NUMBER(4),    

    CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),   
    CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID),
    CONSTRAINT AK_GROUP_ID UNIQUE(GROUP_ID)
);

如果错误的真正原因是缺少唯一性,则必须使用复合PK来确保唯一性:

CREATE TABLE GROUPS_PLUS_SUPPLIERS  
(
    PRODUCT_GROUP_SUPPLIER_ID NUMBER(3),
    GROUP_ID NUMBER(4),    
    GROUP_NAME VARCHAR2(255),   
    SUPPLIER_ID NUMBER(4),    

    CONSTRAINT GROUPS_PLUS_SUPPLIERS_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID,GROUP_ID,GROUP_NAME,SUPPLIER_ID),   
    CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
);

这将允许您添加重复的组ID值,同时满足所需的匹配唯一性

产品
表上的约束
FK\u集团+供应商ID
不应引用
集团+供应商(集团ID)
。它应该参考
组加供应商(产品组供应商ID)

...
CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUPS_PLUS_SUPPLIERS(PRODUCT_GROUP_SUPPLIER_ID)
...
如果您真的打算将其仅作为
GROUP\u ID
的FK,那么应该有一个
GROUP
表,其中
GROUP\u ID
是您应该引用的主键

...
CONSTRAINT FK_GROUP_PLUS_SUPPLIERS_ID FOREIGN KEY (PRODUCT_GROUP) REFERENCES GROUP(GROUP_ID)
...

由于您的
GROUP\u ID
列不是唯一的,并且不能对非唯一值(它与哪一行相关?)进行外键约束,并且假定您的
GROUP\u PLUS\u SUPPLIERS
表也使用
SUPPLIER\u ID
,那么您必须有一个复合外键:

CREATE TABLE GROUPS_PLUS_SUPPLIERS (
    PRODUCT_GROUP_SUPPLIER_ID NUMBER(3), -- better not to have this column
    GROUP_ID NUMBER(4),
    GROUP_NAME VARCHAR2(255), -- violates 2nd normal form!
    SUPPLIER_ID NUMBER(4),

    CONSTRAINT PRODUCT_GROUP_SUPPLIER_ID_PK PRIMARY KEY (PRODUCT_GROUP_SUPPLIER_ID),
    CONSTRAINT FK_SUPPLIER_ID FOREIGN KEY (SUPPLIER_ID) REFERENCES SUPPLIERS (SUPPLIER_ID)
    -- A new constraint
    CONSTRAINT UQ_PRODUCT_GROUP_SUPPLIER_ID_GROUP_ID UNIQUE (SUPPLIER_ID, GROUP_ID)
);

CREATE TABLE PRODUCTS (
    PRODUCT_ID NUMBER (4),
    PRODUCT_DESCRIPTION VARCHAR2 (255),
    PRODUCT_SIZE VARCHAR2 (10),
    PRODUCT_GROUP NUMBER (4),
    PRODUCT_PRICE NUMBER(4),
    NO_IN_STOCK NUMBER (4),
    REORDER_LEVEL NUMBER (4),

    CONSTRAINT PRODUCTS_ID_PK PRIMARY KEY (PRODUCT_ID),
    -- a changed constraint
    CONSTRAINT FK_GROUPS_PLUS_SUPPLIERS_SUPPLIER_ID_GROUP_ID 
       FOREIGN KEY ( SUPPLIER_ID, PRODUCT_GROUP)
       REFERENCES GROUPS_PLUS_SUPPLIERS(SUPPLIER_ID, GROUP_ID)
);
我可能在这个建议中偏离了基准,而FK需要指向
GROUPS
表,如果该表不存在,则需要创建该表。让您的FK指向
产品组供应商ID
列也是一种可能的解决方案,但我向您保证,这样做会给您带来严重的问题,当您发现要按组查询产品表时,您总是会被迫加入另一个表。我很有信心地预测,如果你那样做,你将深感遗憾

数据库设计也存在一些严重问题

  • 查看更新后的示例,了解您希望在
    集团加供应商
    表中得到什么,如果
    集团名称
    出现在该表中,那将非常糟糕,因为这违反了规则。您需要一个带有
    GROUP\u ID
    GROUP\u NAME
    列的
    GROUPS

  • GROUPS\u PLUS\u SUPPLIERS
    表似乎是一个多对多联接表,几乎可以肯定它不需要自己的ID列。我保证99%的情况下这是正确的,并且对于引用此逻辑关系的任何其他表(供应商ID和集团ID之间的唯一关系),最好只使用复合键。你会为此感谢我的

  • 数字(4)
    似乎太低了。你确定永远不会有超过9999种产品吗?即使对供应商来说,这听起来也太低了。以后不要再让自己头疼了,让它们足够大以适应真实的企业级场景

  • 另外,请原谅我没有限制,但是你的命名方案需要一些工作。我知道Oracle的一些旧版本需要全部大写字母,但不能处理小写字母,所以我想如果您正在使用的是小写字母,请忽略这一部分


  • 不要将所有大写字母与下划线一起使用。至少使用Pascal大小写,或所有小写加下划线。最好是
    GroupID
    GroupID
    等等
  • 所有表中的列名称都相同。不要在一个表中称之为
    GROUP\u ID
    ,在另一个表中称之为
    PRODUCT\u GROUP
    。坦率地说,不这样做是荒谬的,并且会导致未来开发者对您的困惑和仇恨。下一个开发人员使用此数据库后,你最好不知道你的地址
  • GROUPS\u PLUS\u SUPPLIERS
    太罗嗦了。只需使用
    SUPPLIERS\u group
  • 不要将表名放在每个可能的列之前。别这样。我认为对于许多表(如
    Description
    )通用的列名来说,这是可以的,但对于其他表则不可以。(事实上,这就是为什么在我自己的表中,我完全停止使用
    Descr
    Description
    ,现在只将列称为表名的单数——尽管我的表也是单数的,例如
    ProductStatus
    表将使用name列
    ProductStatus
    ,而不是
    ProductStatusDescription
    描述
    或其他怪物。)
  • 以下是我认为更合理的命名方案和数据库设计:

    CREATE TABLE Groups (
       GroupID NUMBER(4),
       GroupName VARCHAR2(255), -- I would normally call this Group but that's reserved
    
       CONSTRAINT PK_Groups PRIMARY KEY (GroupID),
       CONSTRAINT UQ_Groups_GroupName UNIQUE (GroupName)
    );
    
    CREATE TABLE SupplierGroups (
        GroupID NUMBER(4),    
        SupplierID NUMBER(4),
    
        CONSTRAINT PK_SupplierGroups PRIMARY KEY (SUPPLIER_ID, GROUP_ID),   
        CONSTRAINT FK_SupplierID FOREIGN KEY (SupplierID) REFERENCES Suppliers (SupplierID),
        CONSTRAINT FK_GroupID FOREIGN KEY (GroupID) REFERENCES Groups (GroupID)
    );
    
    CREATE TABLE Products (
        ProductID NUMBER (4),
        ProductDescription VARCHAR2 (255),
        Size VARCHAR2 (10),
        GroupID NUMBER (4),
        Price NUMBER(4),
        NoInStock NUMBER (4),
        ReorderLevel NUMBER (4),
    
        CONSTRAINT PK_Products PRIMARY KEY (ProductID),
        CONSTRAINT FK_Products_SupplierID_GroupID FOREIGN KEY (SupplierID, GroupID)
           REFERENCES SupplierGroups (SupplierID, GroupID)
    );
    

    SUPPLIER\u ID
    是否在
    SUPPLIERS
    表中声明为主键?其中添加了5588等id?是的,它被声明为主键使用数字(4)背后的想法是什么?似乎有一个代码错误正在等待发生。尝试了这个操作,但当我尝试添加值时,它会抛出一个错误“code”ORA-00001:唯一约束(AKU GROUP_ID)违反了“code”否。您不能插入一个与另一个GROUP_ID相同的行。您无法同时实现组_ID的外键和允许列中存在重复值。这就是我正在尝试做的。我正在尝试在组_ID中添加重复的值,因此不能将组_ID用作此外键关系中的主键。这违反了外键的工作方式。我所要做的就是为组_ID添加重复的值,因为一个组有不同的供应商。将表中的每一列都作为主键的一部分不是一个好主意。你意识到这会使所有这些列在表中任何索引的每一行中都被复制吗?@ErikE,如果PK提供了完整的覆盖率,为什么还要添加更多索引?永远不要通过
    组ID
    支持查询
    组加供应商\u PK