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种产品吗?即使对供应商来说,这听起来也太低了。以后不要再让自己头疼了,让它们足够大以适应真实的企业级场景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
表