테이블에 저장할 데이터를 제약하는 규칙
입력한 데이터와 제약조건을 비교해서 TRUE면 데이터가 입력되고
FALSE면 데이터가 입력되지 않는다
데이터베이스의 정확성/일관성을 유지하기위해 사용한다
-> 데이터의 무결성
제약조건의 종류
CREATE TABLE TABLE_NOTNULL(
LOGIN_ID VARCHAR2(20) NOT NULL, /*생성할 컬럼에 NOT NULL이라는 제약조건을 걸엇다*/
LOGIN_PWD VARCHAR2(20) NOT NULL,
TEL VARCHAR2(20)
);
INSERT INTO TABLE_NOTNULL
VALUES('TEST_ID_01', NULL, NULL);
/*LOGIN_PWD의 제약조건은 NULL이 올수 없기때문에 데이터를 넣을수가없다*/
제약조건이 달린 컬럼은 데이터의 입출력시에 지정한 제약조건이 붙는다
SELECT OWNER, CONSTRAINT_NAME, CONSTRAINT_TYPE, TABLE_NAME
FROM USER_CONSTRAINTS;
SELECT * FROM USER_CONSTRAINTS;
출력된 결과값에서
CONSTRAINT_TYPE 을 보면 P, R, C 가있는데
각각 PRIMARY KEY, FOREIGN KEY, CHECK(NOT NULL) 이라는 뜻이다
U 는 UNIQUE다
CONSTRAINT_NAME -> 제약조건의 이름인데 시스템이 알아서 정해버린다
이를 내가 원하는 이름으로 정해줄 수 있다
CREATE TABLE TABLE_NOTNULL2(
LOGIN_ID VARCHAR2(20) CONSTRAINT TBLNN2_LOGID_NN NOT NULL,
LOGIN_PWD VARCHAR2(20) CONSTRAINT TBLNN2_LOGPW_NN NOT NULL,
TEL VARCHAR2(20)
);
/*CONSTRAINT TBLNN2_LOGID_NN 이부분이 생략되어 있으면 시스템이 이름을 정하지만
이렇게 지정해주면 CONSTRAINT_NAME을 나중에 검색하더라도 쉽게 알아볼수 있다
TBLNN2_LOGID_NN -> TABLE_NOTNULL2의 LOGID는 NOT NULL이다 라고 이름을 지어줫다*/
테이블을 생성할때 제약조건 앞에 CONSTRAINT 제약조건이름 으로
제약조건에 이름을 붙여서 생성할 수 있다
이름을 붙여주면 가독성이 올라가기 때문에 작업할때 편해진다
ALTER TABLE TABLE_NOTNULL2
MODIFY(TEL NOT NULL); /*TEL은 아무 제약조건이 없었다 새로 NOT NULL이라는 조건이 생겼다*/
하지만 바꾸려고 하는 컬럼안의 데이터가 이미 NULL값이 존재한다면?
제약조건을 NULL로 바꿀수 없다
그럴경우 NULL데이터를 NULL이 아닌 데이터로 수정한후 제약조건을 걸어야한다
UPDATE TABLE_NOTNULL
SET TEL = '010-0000-0000'
WHERE TEL IS NULL; /*NULL값의 DATA를 000으로 변경햇다*/
ALTER TABLE TABLE_NOTNULL
MODIFY(TEL NOT NULL); /*다시 실행하면 잘 적용됬다*/
SELECT * FROM USER_CONSTRAINTS; /*조회해보면 TEL에 NOT NULL의 제약조건이 생긴걸 확인할수 있다*/
ALTER TABLE TABLE_NOTNULL
RENAME CONSTRAINT SYS_C0011066 TO TBLNN_TEL_NN; /*시스템이 정해준 CONSTRAINT NAME을
내가 원하는 이름으로 변경했다*/
제약조건의 이름수정하기 RENAME
제약조건의 조건수정하기 MODIFY
ALTER TABLE TABLE_NOTNULL
DROP CONSTRAINT TBLNN_TEL_NN; /*CONSTRAINT명령을 사용할때 CONSTRANT NAME이 계속
사용이 되기때문에 USER_CONSTRAINTS 를 DESC 테이블 했던것처럼 체크해서 사용하면 된다*/
열에 저장할 데이터의 중복을 허용하지 않는 제약조건
NULL값이 여러개가 있어도 데이터의 중복이 아닌 데이터가 없다는 뜻이므로
NULL값은 여러개가 들어올수가 있다
UNIQUE 제약조건을 걸면 자동으로 INDEX도 생성된다
CREATE TABLE TABLE_UNIQUE(
LOGIN_ID VARCHAR2(20) UNIQUE,
LOGIN_PWD VARCHAR2(20) CONSTRAINT TBU_LOGPW_NN NOT NULL,
TEL VARCHAR2(20)
);
UNIQUE로 생성된 로그인 아이디 컬럼은 중복값이 들어가지지 않는다
INSERT INTO TABLE_UNIQUE(LOGIN_ID, LOGIN_PWD, TEL)
VALUES('TEST_ID_01', 'TEST_PW_01', 010-1234-5678);
두번 넣으려고하면 제약조건에 위배된다는 오류가 나온다
INSERT INTO TABLE_UNIQUE(LOGIN_ID, LOGIN_PWD, TEL)
VALUES('TEST_ID_02', 'TEST_PW_01', 010-1234-5678);
이름을 달리해주면 잘들어간다
INSERT INTO TABLE_UNIQUE
VALUES(NULL, 'TEST_PW_01', 010-1234-5678);
이와같이 데이터를 입력하면 UNIQUE지만 계속 데이터가 들어간다
상황1. UNIQUE컬럼의 데이터를 수정하기
제약조건을 맞추면서 데이터를 수정하기때문에 다음과같은 상황이 발생할수있다
UPDATE TABLE_UNIQUE
SET LOGIN_ID = 'TEST_PW_01'
WHERE LOGIN_ID IS NULL;
NULL값이 여러개가 들어가있으면 데이터를 수정할때 데이터가 중복이 될수있다
UNIQUE를 쓸때 이를 조심해야한다
WHERE로 조건을 다른 컬럼에 적용시켜서 하나씩 바꿔줄수도 있겠지만
만약 다른 컬럼마저 구분이 안된다면 하나씩 수정은 불가능하다
상황2. 컬럼의 제약조건을 UNIQUE로 수정하기
ALTER TABLE TABLE_UNIQUE
MODIFY(TEL UNIQUE);
TEL 컬럼에 UNIQUE로 제약조건을 걸고 싶었지만
안에 있는 데이터를 봤더니 중복되는 데이터들이 있어서
UNIQUE제약조건에 위배되서 수정이 불가능 했다
중복되는 데이터를 먼저 수정을 해야 UNIQUE 제약조건도 수정이 가능하다
마찬가지로 제약조건의 이름을 찾아서 삭제해줄 수 있다
ALTER TABLE TABLE_UNIQUE
DROP CONSTRAINT TBLUNQ_TEL_UNQ;
제약조건의 이름을 정해주어야하는 이유가 나오는데
만약 사용자가 지정하지 않고 SELECT * FROM USER_CONSTRAINTS; 을 해보면
SYS_C0011073
SYS_C0011068
SYS_C0011061
이런형태로 나오기때문에 내가 원하는 제약조건을 찾기가 힘들다 그래서 명명해주는것이 좋다
유일하게 하나만 있는 값 UNIQUE + NOT NULL
테이블당 하나의 컬럼에만 적용가능하다
자동으로 인덱스가 만들어진다
CREATE TABLE TABLE_PK(
TEST_LOGIN_ID VARCHAR2(20) CONSTRAINT TVLPK_LOGID_PK PRIMARY KEY,
TEST_LOGIN_PWD VARCHAR2(20) CONSTRAINT TVLPK_LIGPWD_NN NOT NULL,
TEST_TEL VARCHAR2(20)
);
SELECT * FROM USER_CONSTRAINTS; 로 제약조건을 찾으려고보니
지금까지 만든 제약조건이 너무 많아서 찾기 힘들어졌다 그럴때는
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME LIKE'%TABLE_PK%';
이런식으로 테이블명을 지정해서 제약조건을 검색할 수 있다
조건을 검색해보면 자동으로 인덱스 까지 생긴걸 확인할수있다
인덱스 이름도 PK의 이름과 똑같다
INSERT INTO TABLE_PK
VALUES('TEST_ID', 'TEST_PWD', 1234-1234);
/*값을 두번 넣어보면 제약조건때문에 들어가지지 않는다*/
INSERT INTO TABLE_PK
VALUES(NULL, 'TEST_PWD', 1234-1234);
/*NULL로 넣어도 제약조건 때문에 들어가지지 않는다*/
다른 제약조건과 마찬가지로 수정, 삭제가 같은 방식으로 가능하다
ALTER TABLE 테이블
MODIFY(컬럼 제약조건);
ALTER TABLE 테이블
DROP CONSTRAINT 제약조건이름;
ALTER TABLE 테이블
RENAME CONSTRAINT 기존제약조건이름
TO 바꿀제약조건이름;
자주 사용하는 컬럼?
PRIMARY KEY는 데이터의 고유성을 보장하므로 ID 열에 자주 쓰인다
PRIMARY KEY는 테이블에 엔터티 무결성을 적용
ENTITY 엔터티
-> 실체/객체라는 의미
깊게 들어가면 좀더 많은 정보가 있지만 일단 이정도로 알아둘것
엔터티 무결성이라는건 객체가 정확하고 일관성있다는 뜻이다
다른 테이블과 관계를 맺어야 하는 제약조건
어떤 테이블에서 PRIMARY KEY 제약조건을 지정한 컬럼을
다른 테이블에서 FOREIGN KEY 제약조건으로 컬럼을 지정할수 있다
CREATE TABLE TABLE_FK(
TEST_LOGIN_ID VARCHAR2(20) CONSTRAINT TVLFK_LOGID_FK
REFERENCES TABLE_PK(TEST_LOGIN_ID),
TEST_LOGIN_PWD VARCHAR2(20) CONSTRAINT TVLFK_LOGPWD_NN NOT NULL,
TEST_TEL VARCHAR2(20)
);
만드는법이 조금 다른데 FOREIGN KEY 라는 문구를 사용하지 않고
(문구를 사용해서 만드는 방법도 있다 지금 방법이 좀더 쉽다고 생각한다)
REFERENCES 부모테이블(PRIMARY KEY 컬럼) 형식으로 적어주면
해당컬럼이 자동으로 해당 PRIMARY KEY에 대한 FOREIGN KEY로 제약조건이 생긴다
KEY를 아주 많이 만들경우에는 문법이 길어질 수도 있지만
보통 KEY값은 그렇게 많은 경우가 없기때문에 큰 문제가 없다고 생각한다
해당 컬럼의 데이터에 사용자가 원하는 조건을 걸어서
TRUE일때는 데이터가 들어가고 FALSE면 못들어가는 제약조건
CREATE TABLE TABLE_CHECK(
TEST_LOGIN_ID VARCHAR2(20) CONSTRAINT TVLCK_LOGID_PK PRIMARY KEY,
TEST_LOGIN_PWD VARCHAR2(20) CONSTRAINT TVLCK_LOGPW_CK
CHECK(LENGTH(TEST_LOGIN_PWD) > 3),
TEST_TEL VARCHAR2(20)
);
CHECK() 안에는 WHERE 절 뒤에오는 문법같은 형태의 조건절을 사용한다
하지만 BETWEEN같은 문법은 애초에 성립이 안되기 때문에 잘 골라서 사용해야한다
데이터의 무결성을 위해 자주 쓰일것 같다
제약조건을 잘 활용하면 엉뚱한 데이터가 들어가는 일을
미리 방지할수 있을것이다
데이터베이스를 통해 관리할 데이터를 저장하는 테이블
DB를 운영하는데 필요한 중요한 데이터를 보관한다
USER_XXX : 현재 데이터베이스 접속자가 소유한 객체정보
ALL_XXX : 접속자가 소유한 객체 또는 다른 사용자가 소유한 객체중 사용허가를 받은 객체
DBA_XXX : SYSTEM, SYS 사용자만 열람 가능한 테이블
V$_XXX : 성능 관련 정보
일반 개발자는 핵심적인 몇개 빼고는 사용할일이 드물다
(제약조건을 확인하기 위해서 사용한 USER_XXX가 데이터사전에 해당된다)
이정도가 있다고 알아만 두자