【问题标题】:checking foreign key in SQL, is it right? [closed]在SQL中检查外键,对吗? [关闭]
【发布时间】:2016-03-18 05:47:09
【问题描述】:

我只需要你的帮助,你能检查一下我是否在 SQL Server 中正确地完成了外键吗?

我是 SQL 新手,所以对愚蠢的问题感到抱歉。

如果一切正常,我可以开始填充数据了吗?

--CREATING EMPLOYEE TABLE
CREATE TABLE EMPLOYEE(
[ID] INT IDENTITY(1,1) NOT NULL, 
[FIRST_NAME] NVARCHAR(25) NOT NULL,
[LAST_NAME] NVARCHAR(25) NOT NULL,
[EMAIL] nvarchar(60) NOT NULL CONSTRAINT UQ_EMPLOYEE_email UNIQUE,
[PHARMACY_ID] INT NOT NULL,
CONSTRAINT PK_EMPLOYEE_ID PRIMARY KEY (ID));

--CREATING PHARMACY TABLE
CREATE TABLE PHARMACY (
[ID] INT IDENTITY(1, 1) NOT NULL, 
[NAME] NVARCHAR(25),
[ADDRESS] NVARCHAR(25) NULL,
[PHONE] nvarchar(24) NULL CHECK(PHONE like '(___)-__-___ __ __'),
[EID] [INT] NOT NULL
CONSTRAINT PK_PHARMACY_ID PRIMARY KEY (ID));

--CREATE SUPPLIERS TABLE
CREATE TABLE SUPPLIERS(
[ID] INT IDENTITY(1,1) NOT NULL,
[NAME] NVARCHAR(25),
[ADDRESS] NVARCHAR(25) NULL,
[DRUGSID] [INT] NOT NULL,
CONSTRAINT PK_SUPPLIERS_ID PRIMARY KEY (ID));

--CREATE TABLE DRUGS
CREATE TABLE DRUGS(
[ID] INT IDENTITY(1,1) NOT NULL,
[NAME] NVARCHAR(25),
[QUANTITY] INT NULL,
[ORDERID] [INT] NULL,
[SUPPLIERID] [INT] NULL,
CONSTRAINT PK_DRUGS_ID PRIMARY KEY(ID));

--CREATEING TABLE ORDERS
CREATE TABLE ORDERS (
[ID] INT IDENTITY(1,1) NOT NULL,
[ONAME] NVARCHAR(25) NOT NULL,
[ODATE] DATETIME,
[OQUANTITY] INT NOT NULL,
[SUPPLIERID] [INT] NOT NULL,
[DRUGID] [INT] NOT NULL,
CONSTRAINT PK_ORDERS_ID PRIMARY KEY(ID));

--CREATING TABLE MANAGER TABLE 
CREATE TABLE MANAGER (
[PASSPORTNO] INT IDENTITY(1,1) NOT NULL,
[HOURLYPAY] DECIMAL(5,2) NULL,
[LANGUAGE_SKILLS] NVARCHAR(25) NULL
CONSTRAINT PK_MANAGER_NO PRIMARY KEY (PASSPORTNO));

--CREATING TABLE SALES ASSISTANT
CREATE TABLE SALES_ASSISTANT (
[PASSPORTNO] INT IDENTITY(1,1) NOT NULL,
[SALARY] DECIMAL(5,2) NULL
CONSTRAINT PK_SALES_ASSISTANT_NO PRIMARY KEY (PASSPORTNO));

-- FOREIGN KEYs CREATION
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_PHARMACYID FOREIGN KEY(PHARMACY_ID) 
REFERENCES PHARMACY(ID) ON DELETE CASCADE ON UPDATE CASCADE

ALTER TABLE PHARMACY ADD CONSTRAINT FK_EID FOREIGN KEY(EID) 
REFERENCES EMPLOYEE(ID) ON DELETE NO ACTION ON UPDATE NO ACTION

ALTER TABLE SUPPLIERS ADD CONSTRAINT FK_DRUGID FOREIGN KEY(DRUGSID) 
REFERENCES DRUGS(ID) ON DELETE NO ACTION ON UPDATE NO ACTION

ALTER TABLE DRUGS ADD CONSTRAINT FK_ORDERID FOREIGN KEY(ORDERID) 
REFERENCES ORDERS(ID) ON DELETE NO ACTION ON UPDATE NO ACTION


ALTER TABLE DRUGS ADD CONSTRAINT FK_SUPPLIERS FOREIGN KEY(SUPPLIERID) 
REFERENCES SUPPLIERS(ID) ON DELETE NO ACTION ON UPDATE NO ACTION


ALTER TABLE ORDERS ADD CONSTRAINT FK_SUPPLIERS_OR FOREIGN KEY(SUPPLIERID) 
REFERENCES SUPPLIERS(ID) ON DELETE NO ACTION ON UPDATE NO ACTION

ALTER TABLE ORDERS ADD CONSTRAINT FK_DRUGID_OR FOREIGN KEY(DRUGID) 
REFERENCES DRUGS(ID) ON DELETE NO ACTION ON UPDATE NO ACTION

【问题讨论】:

  • @lad2025 没有标记 MySQL
  • 您是否考虑过重命名每个 ID 字段,以便更清楚地知道哪个是哪个,以及什么连接到什么?示例:DrugId 而不是 ID。
  • @destination-data 您是否认为 ID 是表 PK 的好名称?哪个是哪个? Drug.ID

标签: sql sql-server tsql foreign-keys primary-key


【解决方案1】:

您可以检查您使用此查询设置的外键

SELECT  
     KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME 
    ,KCU1.TABLE_NAME AS FK_TABLE_NAME 
    ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME 
    ,KCU1.ORDINAL_POSITION AS FK_ORDINAL_POSITION 
    ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME 
    ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME 
    ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME 
    ,KCU2.ORDINAL_POSITION AS REFERENCED_ORDINAL_POSITION 
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC 

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1 
    ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG  
    AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA 
    AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME 

INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU2 
    ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG  
    AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA 
    AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME 
    AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION 

还有一点: 始终创建您的脚本,以便您可以在必要时运行它 N 次。 因此,要么在创建外键之前删除它,要么仅在它不存在时才创建它。表也​​是如此(如果它们包含数据,请不要删除它们)。

另外,如果你创建了一个外键,你应该检查所有被引用的表是否存在,并检查被引用的表是否设置了主键。

编辑: 一个提示,快速眩光:
我会检查你是否真的需要 DATETIME。
如果您只需要日期,请使用日期而不是日期时间。

【讨论】:

  • 我不认为 N​​uriddin 正在寻找从数据库中检索定义的语句。如果设计正确,她/他正在寻求建议。
  • @a_horse_with_no_name:是的,但也可以理解为“我真的设置了所有外键吗”。
【解决方案2】:

这就是您进行 FK 的方式,但数据设计看起来不正确。您没有指向药物的订单点和指向订单的药物点。阅读 3NF。供应商没有单一的药物。 DrugsID 可能有一个 S,但它仍然是单数。这种数据设计是不正确的。

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2021-07-22
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多