如果我有包含相同值的行,我应该如何 link 我的主键和外键?

How should I link my Primary Keys and Foreign keys if I have rows containing the same values?

我必须使用提供的数据创建 DDL 脚本:

您可以做出以下假设:

  1. 每个项目有一位经理
  2. 每个项目都分配了很多员工。 Hours 属性表示每个员工在相应项目上工作的小时数,rating 属性是该员工在该项目上的工作获得的评级。
  3. 预算和开始日期是指项目的预算和开始日期
  4. Emp_Manager是员工的经理,可能与项目经理不同

我已经把这些转化成3NF了:

a.  Employee_T(Emp_Id, Emp_Salary, Emp_dept)
b.  Project_T(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
c.  EmployeeLine_T(Emp_Id, Proj_Name, Hours, Rating)
d.  EmpMgr_T(Emp_Dept, Emp_Manager)

这是我创建的 DDL:

BEGIN

  --Bye Tables!
  FOR i IN (SELECT ut.table_name
              FROM USER_TABLES ut) LOOP
    EXECUTE IMMEDIATE 'drop table '|| i.table_name ||' CASCADE CONSTRAINTS ';
  END LOOP;

END;

CREATE TABLE PROJECT_T
(
    Proj_Name       VARCHAR2(25)    NOT NULL,
    Proj_Mgr        VARCHAR2(25),
    Proj_Budget     NUMBER          NOT NULL,
    Start_Date      DATE            NOT NULL,
    CONSTRAINT Proj_Name_PK
        PRIMARY KEY (Proj_Name)
);

INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Jupiter','Smith',100000,'15-JAN-2015');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Jupiter','Smith',100000,'15-JAN-2015');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Jupiter','Smith',100000,'15-JAN-2015');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Maxima','Lee',200000,'1-MAR-2014');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Maxima','Lee',200000,'1-MAR-2014');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Maxima','Lee',200000,'1-MAR-2014');

CREATE TABLE MANAGERS_T
(
    Emp_Dept            NUMBER          NOT NULL,
    Emp_Manager         VARCHAR2(25)    NOT NULL,
    CONSTRAINT Emp_Dept_PK
        PRIMARY KEY (Emp_Dept)
);

INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (10,'Levine');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (12,'Jones');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (10,'Levine');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (10,'Levine');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (10,'Levine');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (15,'Jones');

CREATE TABLE EMPLOYEE_T
(
    Emp_Id          VARCHAR2(4)     NOT NULL,
    Emp_Salary      NUMBER,
    Emp_Dept        NUMBER          NOT NULL,  
    CONSTRAINT Emp_Id_PK
        PRIMARY KEY (Emp_Id),
    CONSTRAINT Emp_Dept_FK
        FOREIGN KEY (Emp_Dept) REFERENCES MANAGERS_T(Emp_Dept)
); 

INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E101',60000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E105',55000,12);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E110',43000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E101',60000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E110',43000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E120',45000,10);

CREATE TABLE EMPLOYEELINE_T
(
    Emp_Id          VARCHAR(4)     NOT NULL,
    Proj_Name       VARCHAR2(25)    NOT NULL,
    Hours           NUMBER,
    Rating          NUMBER,
    CONSTRAINT EmpID_ProjName_PK
        PRIMARY KEY(Emp_Id,Proj_Name),
    CONSTRAINT Proj_Name_FK    
        FOREIGN KEY (Proj_Name) REFERENCES PROJECT_T(Proj_Name),
    CONSTRAINT Emp_Id_FK    
        FOREIGN KEY (Emp_Id) REFERENCES EMPLOYEE_T(Emp_Id)
);

INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E101','Jupiter',25,9);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E105','Jupiter',40,0);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E110','Jupiter',10,8);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E101','Maxima',15,0);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E110','Maxima',30,0);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E120','Maxima',15,0);

Here's a GitHub Link

这就是我的表应该如何使用它们的主键和外键。当我创建表格时,它们 运行 很好。问题是当我开始向其中插入值时。

我收到诸如违反唯一约束之类的错误,因为存在重复的值。我该怎么做?

DDL 没问题,问题出在插入脚本上。检查以下脚本:

BEGIN

  --Bye Tables!
  FOR i IN (SELECT ut.table_name
              FROM USER_TABLES ut) LOOP
    EXECUTE IMMEDIATE 'drop table '|| i.table_name ||' CASCADE CONSTRAINTS ';
  END LOOP;

END;

CREATE TABLE PROJECT_T
(
    Proj_Name       VARCHAR2(25)    NOT NULL,
    Proj_Mgr        VARCHAR2(25),
    Proj_Budget     NUMBER          NOT NULL,
    Start_Date      DATE            NOT NULL,
    CONSTRAINT Proj_Name_PK
        PRIMARY KEY (Proj_Name)
);

INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Jupiter','Smith',100000,'15-JAN-2015');
INSERT INTO PROJECT_T
(Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
VALUES ('Maxima','Lee',200000,'1-MAR-2014');

CREATE TABLE MANAGERS_T
(
    Emp_Dept            NUMBER          NOT NULL,
    Emp_Manager         VARCHAR2(25)    NOT NULL,
    CONSTRAINT Emp_Dept_PK
        PRIMARY KEY (Emp_Dept)
);

INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (10,'Levine');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (12,'Jones');
INSERT INTO MANAGERS_T
(Emp_Dept, Emp_Manager)
VALUES (15,'Jones');

CREATE TABLE EMPLOYEE_T
(
    Emp_Id          VARCHAR2(4)     NOT NULL,
    Emp_Salary      NUMBER,
    Emp_Dept        NUMBER          NOT NULL,  
    CONSTRAINT Emp_Id_PK
        PRIMARY KEY (Emp_Id),
    CONSTRAINT Emp_Dept_FK
        FOREIGN KEY (Emp_Dept) REFERENCES MANAGERS_T(Emp_Dept)
); 

INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E101',60000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E105',55000,12);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E110',43000,10);
INSERT INTO EMPLOYEE_T
(Emp_Id,Emp_Salary,Emp_Dept)
VALUES ('E120',45000,10);

CREATE TABLE EMPLOYEELINE_T
(
    Emp_Id          VARCHAR(4)     NOT NULL,
    Proj_Name       VARCHAR2(25)    NOT NULL,
    Hours           NUMBER,
    Rating          NUMBER,
    CONSTRAINT EmpID_ProjName_PK
        PRIMARY KEY(Emp_Id,Proj_Name),
    CONSTRAINT Proj_Name_FK    
        FOREIGN KEY (Proj_Name) REFERENCES PROJECT_T(Proj_Name),
    CONSTRAINT Emp_Id_FK    
        FOREIGN KEY (Emp_Id) REFERENCES EMPLOYEE_T(Emp_Id)
);

INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E101','Jupiter',25,9);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E105','Jupiter',40,NULL);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E110','Jupiter',10,8);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E101','Maxima',15,NULL);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E110','Maxima',30,NULL);
INSERT INTO EMPLOYEELINE_T
(Emp_Id, Proj_Name, Hours, Rating)
VALUES ('E120','Maxima',15,NULL);

I get errors like unique constraint violated because there are values that are repeated. How would I go about this?

不要重复值。

除此之外,经理也是员工:

SQL Fiddle

Oracle 11g R2 架构设置:

CREATE TABLE EMPLOYEE_T
(
    Emp_Id          VARCHAR2(4)     CONSTRAINT Employee__Emp_Id_PK PRIMARY KEY,
    Emp_Salary      NUMBER,
    Emp_Dept        NUMBER          CONSTRAINT Employee__Emp_Dept__NN NOT NULL,
    Name            VARCHAR2(20)
); 

CREATE TABLE MANAGERS_T
(
    Emp_Dept    NUMBER      CONSTRAINT Managers__Emp_Dept__PK PRIMARY KEY,
    Manager_ID  VARCHAR2(4) CONSTRAINT Manager__Manager_ID__FK REFERENCES Employee_T ( Emp_ID )
);

ALTER TABLE Employee_T ADD CONSTRAINT Emp_Dept_FK
  FOREIGN KEY (Emp_Dept) REFERENCES MANAGERS_T(Emp_Dept);

INSERT INTO MANAGERS_T (Emp_Dept, Manager_ID)
SELECT 10,NULL FROM DUAL UNION ALL
SELECT 12,NULL FROM DUAL UNION ALL
SELECT 15,NULL FROM DUAL;

INSERT INTO EMPLOYEE_T (Emp_Id,Emp_Salary,Emp_Dept,Name)
SELECT 'E101',60000,10,'Alice' FROM DUAL UNION ALL
SELECT 'E105',55000,12,'Bob' FROM DUAL UNION ALL
SELECT 'E110',43000,10,'Carol' FROM DUAL UNION ALL
SELECT 'E120',45000,10,'David' FROM DUAL UNION ALL
SELECT 'E001',NULL,10,'Smith' FROM DUAL UNION ALL
SELECT 'E002',NULL,12,'Jones' FROM DUAL UNION ALL
SELECT 'E003',NULL,10,'Levine' FROM DUAL UNION ALL
SELECT 'E004',NULL,12,'Lee' FROM DUAL;

UPDATE MANAGERS_T SET Manager_ID = 'E003' WHERE Emp_Dept = 10;
UPDATE MANAGERS_T SET Manager_ID = 'E002' WHERE Emp_Dept = 12;
UPDATE MANAGERS_T SET Manager_ID = 'E001' WHERE Emp_Dept = 15;

ALTER TABLE Managers_T MODIFY Manager_ID VARCHAR2(4) CONSTRAINT Managers__Manager_ID__NN NOT NULL;

CREATE TABLE PROJECT_T
(
    Proj_Name       VARCHAR2(25)    CONSTRAINT Proj_Name_PK PRIMARY KEY,
    Proj_Mgr        VARCHAR2(4)     CONSTRAINT Project__Proj_Mgr__FK REFERENCES Employee_T ( Emp_ID ),
    Proj_Budget     NUMBER          CONSTRAINT Project__Budget__NN NOT NULL,
    Start_Date      DATE            CONSTRAINT Project__Start_Date__NN NOT NULL
);

INSERT INTO PROJECT_T (Proj_Name, Proj_Mgr, Proj_Budget, Start_Date)
SELECT 'Jupiter','E001',100000, DATE '2015-01-15' FROM DUAL UNION ALL
SELECT 'Maxima','E004',200000,DATE '2014-03-01' FROM DUAL;

CREATE TABLE EMPLOYEELINE_T
(
    Emp_Id          VARCHAR(4)   CONSTRAINT Emp_Id_FK REFERENCES EMPLOYEE_T(Emp_Id),
    Proj_Name       VARCHAR2(25) CONSTRAINT Proj_Name_FK REFERENCES PROJECT_T(Proj_Name),
    Hours           NUMBER,
    Rating          NUMBER,
    CONSTRAINT EmpID_ProjName_PK PRIMARY KEY(Emp_Id,Proj_Name)
);

INSERT INTO EMPLOYEELINE_T (Emp_Id, Proj_Name, Hours, Rating)
SELECT 'E101','Jupiter',25,9 FROM DUAL UNION ALL
SELECT 'E105','Jupiter',40,0 FROM DUAL UNION ALL
SELECT 'E110','Jupiter',10,8 FROM DUAL UNION ALL
SELECT 'E101','Maxima',15,0 FROM DUAL UNION ALL
SELECT 'E110','Maxima',30,0 FROM DUAL UNION ALL
SELECT 'E120','Maxima',15,0 FROM DUAL;

查询 1:

SELECT p.proj_name,
       p.proj_mgr,
       el.emp_id,
       el.hours,
       p.proj_budget,
       p.start_date,
       e.emp_salary,
       m.manager_id,
       e.emp_dept,
       el.rating
FROM   project_t p
       INNER JOIN Employeeline_t el
       ON ( p.proj_name = el.proj_name )
       INNER JOIN employee_t e
       ON ( el.emp_id = e.emp_id )
       INNER JOIN managers_t m
       ON ( e.emp_dept = m.emp_dept )

Results:

| PROJ_NAME | PROJ_MGR | EMP_ID | HOURS | PROJ_BUDGET |           START_DATE | EMP_SALARY | MANAGER_ID | EMP_DEPT | RATING |
|-----------|----------|--------|-------|-------------|----------------------|------------|------------|----------|--------|
|    Maxima |     E004 |   E120 |    15 |      200000 | 2014-03-01T00:00:00Z |      45000 |       E003 |       10 |      0 |
|   Jupiter |     E001 |   E110 |    10 |      100000 | 2015-01-15T00:00:00Z |      43000 |       E003 |       10 |      8 |
|    Maxima |     E004 |   E110 |    30 |      200000 | 2014-03-01T00:00:00Z |      43000 |       E003 |       10 |      0 |
|   Jupiter |     E001 |   E101 |    25 |      100000 | 2015-01-15T00:00:00Z |      60000 |       E003 |       10 |      9 |
|    Maxima |     E004 |   E101 |    15 |      200000 | 2014-03-01T00:00:00Z |      60000 |       E003 |       10 |      0 |
|   Jupiter |     E001 |   E105 |    40 |      100000 | 2015-01-15T00:00:00Z |      55000 |       E002 |       12 |      0 |