종류 | 설명 |
---|---|
NOT NULL | 지정한 열에 NULL을 허용하지 않는다. NULL을 제외한 데이터의 중복은 허용된다. |
UNIQUE | 지정한 열이 유일한 값을 가져야 한다. 즉, 중복될 수 없다. 단, NULL은 값의 중복에서 제외된다. |
PRIMARY KEY | 지정한 열이 유일한 값이면서 NULL을 허용하지 않는다. PRIMARY KEY는 테이블에 하나만 지정 가능하다. |
FOREIGN KEY | 다른 테이블의 열을 참조하여 존재하는 값만 입력할 수 있다. |
CHECK | 설정한 조건식을 만족하는 데이터만 입력 가능하다. |
종류 | 설명 |
---|---|
영역 무결성 (domain integrity) | 열에 저장되는 값의 적정 여부를 확인. 자료형, 적절한 형식의 데이터, NULL의 여부 같은 정해 놓은 범위를 만족하는 데이터임을 규정 |
개체 무결성 (entity integrity) | 테이블 데이터를 유일하게 식별할 수 있는 기본키는 반드시 값을 가지고 있어야 하며 NULL이 될 수 없고 중복될 수도 없음을 규정 |
참조 무결성 (referential integrity) | 참조 테이블의 외래키 값은 참조 테이블의 기본키로서 존재해야 하며 NULL이 가능 |
CREATE TABLE TABLE_NOTNULL(
LOGIN_ID VARCHAR(20) NOT NULL,
LOGIN_PWD VARCHAR(20) NOT NULL,
TEL VARCHAR(20)
);
DESC TABLE_NOTNULL;
INSERT INTO TABLE_NOTNULL (LOGIN_ID, LOGIN_PWD, TEL)
VALUES( 'TEST_ID_01', NULL, '010-1234-5678');
INSERT INTO TABLE_NOTNULL (LOGIN_ID, LOGIN_PWD)
VALUES( 'TEST_ID_01', '1234');
SELECT * FROM TABLE_NOTNULL;
UPDATE TABLE_NOTNULL
SET LOGIN_PWD = NULL
WHERE LOGIN_ID = 'TEST_ID_01'; -> 오류 뜬다.
열 이름 | 설명 |
---|---|
OWNER | 제약 조건 소유 계정 |
CONSTRAINT_NAME | 제약 조건 이름(직접 지정하지 않을 경우 오라클이 자동으로 지정함 |
CONSTRAINT_TYPE | 제약 조건 종류 C: CHECK, NOT NULL U: UNIQUE P: PRIMARY KEY R: FOREIGN KEY |
TABLE_NAME | 제약 조건을 지정한 테이블 이름 |
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS;
CREATE TABLE TABLE_NOTNULL2(
LOGIN_ID VARCHAR(20) CONSTRAINT TBLNN2_LGNID_NN NOT NULL,
LOGIN_PWD VARCHAR(20) CONSTRAINT TBLNB2_LGNPW_NN NOT NULL,
TEL VARCHAR2(20)
);
ALTER TABLE TABLE_NOTNULL
MODIFY(TEL NOT NULL);
제약 조건 추가를 위한 명령어를 잘 작성했어도 제약 조건과 맞지 않는 데이터가 이미 있다면 제약 조건 지정이 실패한다.
UPDATE TABLE_NOTNULL
SET TEL = '010-1234-5678'
WHERE LOGIN_ID = 'TEST_ID_01';
SELECT * FROM TABLE_NOTNULL;
ALTER TABLE TABLE_NOTNULL
MODIFY(TEL NOT NULL);
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS;
(CONSTRAINT TYPE이 C면 NOT NULL 또는 CHECK라는 뜻이다.)
ALTER TABLE TABLE_NOTNULL2
MODIFY(TEL CONSTRAINT TBLNN_TEL_NN NOT NULL);
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS;
DESC TABLE_NOTNULL2;
ALTER TABLE TABLE_NOTNULL2
RENAME CONSTRAINT TBLNN_TEL_NN TO TBLNN2_TEL_NN;
ALTER TABLE TABLE_NOTNULL2
DROP CONSTRAINT TBLNN2_TEL_NN;
CREATE TABLE TABLE_UNIQUE(
LOGIN_ID VARCHAR2(20) UNIQUE,
LOGIN_PWD VARCHAR2(20) NOT NULL,
TEL VARCHAR2(20)
);
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TABLE_UNIQUE';
INSERT INTO TABLE_UNIQUE(LOGIN_ID, LOGIN_PWD, TEL)
VALUES('TEST_ID_01', 'PWD01', '010-1234-5678');
SELECT * FROM TABLE_UNIQUE;
INSERT INTO TABLE_UNIQUE(LOGIN_ID, LOGIN_PWD, TEL)
VALUES('TEST_ID_02', 'PWD01', '010-1234-5678');
SELECT * FROM TABLE_UNIQUE;
INSERT INTO TABLE_UNIQUE(LOGIN_ID, LOGIN_PWD, TEL)
VALUES(NULL, 'PWD01', '010-1234-5678');
SELECT * FROM TABLE_UNIQUE;
UPDATE TABLE_UNIQUE
SET LOGIN_ID = 'TEST_ID_01'
WHERE LOGIN_ID IS NULL;
CREATE TABLE TABLE_UNIQUE2(
LOGIN_ID VARCHAR2(20)CONSTRAINT TBLUNQ2_LGNID_UNQ UNIQUE,
LOGIN_PWD VARCHAR(20) CONSTRAINT TBLUNQ2_LGNPWD_NN NOT NULL,
TEL VARCHAR(20)
);
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME LIKE 'TABLE_UNIQUE%';
ALTER TABLE TABLE_UNIQUE
MODIFY(TEL UNIQUE); → 이미 중복값이 존재해서 오류
UPDATE TABLE_UNIQUE
SET TEL = NULL;
SELECT * FROM TABLE_UNIQUE;
ALTER TABLE TABLE_UNIQUE
MODIFY(TEL UNIQUE);
ALTER TABLE TABLE_UNIQUE2
MODIFY(TEL CONSTRAINT TBLUNQ_TEL_UNQ UNIQUE);
ALTER TABLE TABLE_UNIQUE2
RENAME CONSTRAINT TBLUNQ_TEL_UNQ TO TBLUNQ2_TEL_UNQ;
ALTER TABLE TABLE_UNIQUE2
DROP CONSTRAINT TBLUNQ2_TEL_UNQ;
REATE TABLE TABLE_PK(
LOGIN_ID VARCHAR(20) PRIMARY KEY,
LOGIN_PWD VARCHAR(20) NOT NULL,
TEL VARCHAR(20)
);
DESC TABLE_PK;
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME LIKE 'TABLE_PK%';
SELECT INDEX_NAME, TABLE_OWNER, TABLE_NAME
FROM USER_INDEXES
WHERE TABLE_NAME LIKE 'TABLE_PK%';
CREATE TABLE TABLE_PK2(
LOGIN_ID VARCHAR2(20) CONSTRAINT TBLPK2_LGNID_PK PRIMARY KEY,
LOGIN_PWD VARCHAR(20) CONSTRAINT TBLOK2_LGNID_NN NOT NULL,
TEL VARCHAR(20)
);
DESC TABLE_PK2;
INSERT INTO TABLE_PK(LOGIN_ID, LOGIN_PWD, TEL)
VALUES ('TEST_ID_01', 'PWD02', '010-1234-5678');
INSERT INTO TABLE_PK(LOGIN_ID, LOGIN_PWD, TEL)
VALUES (NULL, 'PWD02', '010-1234-5678');
INSERT INTO TABLE_PK(LOGIN_ID, LOGIN_PWD, TEL)
VALUES (NULL, 'PWD02', '010-1234-5678');
SELECT * FROM TABLE_PK;
INSERT INTO TABLE_PK(LOGIN_PWD, TEL)
VALUES ('PWD02', '010-1234-5678');
SELECT * FROM TABLE_PK;
⇒ 둘 다 오류 난다.
CREATE TABLE TABLE_NAME(
COL1 VARCHAR2(20) CONSTRAINT CONSTRAINT_NAME PRIMARY KEY,
COL2 VARCHAR2(20) NOT NULL,
COL3 VARCHAR2(20)
);
CREATE TABLE TABLE_NAME(
COL1 VARCHAR2(20) CONSTRAINT CONSTRAINT_NAME,
COL2 VARCHAR2(20),
COL3 VARCHAR2(20),
PRIMARY KEY (COL1),
CONSTRAINT CONSTAINT_NAME UNIQUE(COL2)
);
외래키, 외부키로도 부르는 FOREIGN KEY는 서로 다른 테이블 간 관계를 정의하는데 사용하는 제약 조건이다.
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME, R_OWNER, R_CONSTRAINT_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME IN ('EMP', 'DEPT');
CONSTRAINTTYPE 열 값이 R일 경우 외래키를 의미한다.
![](https://velog.velcdn.com/images/mini_mouse/post/d4d641d8-1ccb-4ca4-acae-ece48469f786/image.png)
참조 관계를 정의하면 참조하려는 테이블(EMP)에서는 참조 테이블(DEPT)에 존재하는 기본키 열(DPETNO)에 존재하는 값과 NULL만 저장할 수 있다.
FOREIGN KEY가 참조하는 열에 존재하지 않는 데이터 입력하기
INSERT INTO EMP(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES(9999, '홍길동', 'CLERK', '7788', TO_DATE('2017/04/30', 'YYYY/MM/DD'), 1200, NULL, 50);
참조 대상 테이블 = 부모
참조하는 테이블 = 자식으로 표현한다.
CREATE TABLE 테이블 이름(
...(다른 열 정의),
열 자료형 CONSTRAINT [제약 조건 이름] PREFERENCES 참조 테이블(참조할 열)
);
CREATE TABLE 테이블 이름(
...(다른 열 정의),
열 자료형 CONSTRAINT PREFERENCES 참조 테이블(참조할 열)
);
CREATE TABLE 테이블 이름(
...(다른 열 정의),
CONSTRAINT [제약조건이름] FOREIGN KEY(열) PREFERENCES 참조 테이블(참조할 열)
);
CREATE TABLE DEPT_FK(
DEPTNO NUMBER(2) CONSTRAINT DEPTFK_DEPTNO_PK PRIMARY KEY,
DNAME VARCHAR2(14),
LOC VARCHAR2(13)
);
CREATE TABLE EMP_FK(
EMPNO NUMBER(4) CONSTRAINT EMPFK_EMPNO_PK PRIMARY KEY,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2) CONSTRAINT EMPKR_DEPTNO_FK REFERENCES DEPT_FK (DEPTNO)
);
INSERT INTO EMP_FK
VALUES(9999, 'TEST_NMAME', 'TEST_JOB', NULL, TO_DATE('2001/01/01', 'YYYY/MM/DD'), 3000, NULL, 10);
INSERT INTO DEPT_FK
VALUES(10, 'TEST_DNAME', 'TEST_LOC');
SELECT * FROM DEPT_FK;
INSERT INTO EMP_FK
VALUES(9999, 'TEST_NMAME', 'TEST_JOB', NULL, TO_DATE('2001/01/01', 'YYYY/MM/DD'), 3000, NULL, 10);
SELECT * FROM EMP_FK;
DELETE FROM DEPT_FK
WHERE DEPTNO = 10;
CONSTRAINT [제약 조건 이름] REFERENCES 참조 테이블(참조할 열) ON DELETE CASCADE
CONSTRAINT [제약 조건 이름] REFERENCES 참조 테이블(참조할 열) ON DELETE SET NULL
CREATE TABLE TABLE_CHECK(
LOGIN_ID VARCHAR(20) CONSTRAINT TBLCK_LOGINID_PK PRIMARY KEY,
LOGIN_PWD VARCHAR(20) CONSTRAINT TBLCK_LOGINPW_CK CHECK(LENGTH(LOGIN_PWD) >3),
TEL VARCHAR(20)
);
INSERT INTO TABLE_CHECK
VALUES('TEST_ID', '123', '010-1234-5678');
INSERT INTO TABLE_CHECK
VALUES('TEST_ID', '1234', '010-1234-5678');
SELECT * FROM TABLE_CHECK;
제약 조건과는 별개로 특정 열에 저장할 값이 지정되지 않았을 경우 기본값(default)을 지정할 수 있는데, 이때 사용되는 키워드가 DEFAULT이다.
CREATE TABLE TABLE_DEFAULT(
LOGIN_ID VARCHAR(20) CONSTRAINT TBLCK2_LOGINID_PK PRIMARY KEY,
LOGIN_PWD VARCHAR(20) DEFAULT '1234',
TEL VARCHAR(20)
);
INSERT INTO TABLE_DEFAULT VALUES('TEST_ID', NULL, '010-1234-5678');
INSERT INTO TABLE_DEFAULT (LOGIN_ID, TEL) VALUES('TEST_ID2', '010-1234-5678');
SELECT * FROM TABLE_DEFAULT;
NULL 값을 넣겠다고 지정해주면 NULL이 들어가지만, 아예 열 값을 지정하지 않으면 DEFAULT로 지정한 값이 들어가게 된다.
DISABLE [NOVALIDATE / VALIDATE(선택)] CONSTRAINT 제약조건이름;
ENABLE [NONVALIDATE / VALIDATE(선택)] CONSTRAINT 제약조건이름;
Q1. DEPT_CONST 테이블 생성하기
CREATE TABLE DEPT_CONST(
DEPTNO NUMBER(2) CONSTRAINT DEPTCONST_DEPTNO_PK PRIMARY KEY,
DNAME VARCHAR2(14) CONSTRAINT DEPTCONST_DNAME_UNQ UNIQUE,
LOC VARCHAR(13) CONSTRAINT DEPTCONST_LOC_NN NOT NULL
);
Q2. EMP_CONST 테이블 생성하기
CREATE TABLE EMP_CONST(
EMPNO NUMBER(4) CONSTRAINT EMPCONST_EMPNO_PK PRIMARY KEY,
ENAME VARCHAR2(10) CONSTRAINT EMPCONST_ENAME_NN NOT NULL,
JOB VARCHAR2(9),
TEL VARCHAR2(20) CONSTRAINT EMPCONST_TEL_UNQ UNIQUE,
HIREDATE DATE,
SAL NUMBER(7, 2) CONSTRAINT EMPCONST_SAL_CHK CHECK(SAL BETWEEN 1000 AND 9999),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2) CONSTRAINT EMPCONST_DEPTNO_FK REFERENCES DEPT_CONST(DEPTNO)
);
Q3. 위의 두 테이블의 제약 조건 확인하기
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS
WHERE TABLE_NAME LIKE '%CONST%';