{"componentChunkName":"component---src-templates-blog-post-js","path":"/Database/2020-04-17-데이터베이스-데이터무결성/","result":{"data":{"site":{"siteMetadata":{"title":"Hun's Footsteps 🥷","author":"전여훈","siteUrl":"https://jeonyeohun.netlify.app","comment":{"disqusShortName":"","utterances":"jeonyeohun/jeonyeohun.github.io"},"sponsor":{"buyMeACoffeeId":"jeonyeohun"}}},"markdownRemark":{"id":"07396efc-6265-50a9-8dff-36c6a920cb9a","excerpt":"Integrity Constraints Integrity Constraint 는 데이터의 무결성을 유지하기 위한 방법이다. 이전 포스트에서 Integrity Constratins 를 설명했지만, SQL 쿼리로 적용하는 내용은 다루지 않았기 때문에 해당 내용을 정리하자. Constraints on a Single Relation 단일한 테이블에 대해 데이터 무결성을 보장하기 위해서 우리는 다음과 같은 SQL 키워드들을 사용할 수 있다. NOT NULL PRIMARY KEY UNIQUE CHECK(P…","html":"<h1 id=\"integrity-constraints\" style=\"position:relative;\"><a href=\"#integrity-constraints\" aria-label=\"integrity constraints permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrity Constraints</h1>\n<p>Integrity Constraint 는 데이터의 무결성을 유지하기 위한 방법이다. 이전 포스트에서 Integrity Constratins 를 설명했지만, SQL 쿼리로 적용하는 내용은 다루지 않았기 때문에 해당 내용을 정리하자.</p>\n<h1 id=\"constraints-on-a-single-relation\" style=\"position:relative;\"><a href=\"#constraints-on-a-single-relation\" aria-label=\"constraints on a single relation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Constraints on a Single Relation</h1>\n<p>단일한 테이블에 대해 데이터 무결성을 보장하기 위해서 우리는 다음과 같은 SQL 키워드들을 사용할 수 있다.</p>\n<ol>\n<li>NOT NULL</li>\n<li>PRIMARY KEY</li>\n<li>UNIQUE</li>\n<li>CHECK(P)</li>\n</ol>\n<h2 id=\"not-null\" style=\"position:relative;\"><a href=\"#not-null\" aria-label=\"not null permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>NOT NULL</h2>\n<p>NOT NULL 은 어떤 attribute 가 NULL 값을 가지는 것을 허용하지 않기 위해 사용된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span> student <span class=\"token punctuation\">(</span>\n    name <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">NOT</span> <span class=\"token boolean\">NULL</span><span class=\"token punctuation\">,</span>\n    phone <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>이렇게 테이블을 생성하게 되면, phone attribute의 값은 null을 허용하지만 name의 값은 null을 허용하지 않게된다.</p>\n<h2 id=\"unqiue\" style=\"position:relative;\"><a href=\"#unqiue\" aria-label=\"unqiue permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>UNQIUE</h2>\n<p>UNIQUE 는 어떤 attrubute 가 해당 attribute에 대해 중복된 값을 가지는 것을 허용하지 않게 하는 것을 말한다. 즉, 해당 attribute 를 candidate key로 삼는 것이다. candidate key는 유일성과 최소성을 만족하는 key를 말한다. 해당 attribute 하나를 통해 어떤 tuple을 식별할 수 있게되기 때문에, 유일성과 최소성을 만족한다. 하지만 candidate key는 null 값을 가질 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span> student <span class=\"token punctuation\">(</span>\n    name <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">NOT</span> <span class=\"token boolean\">NULL</span><span class=\"token punctuation\">,</span>\n    SSN <span class=\"token keyword\">VARCHAR</span> <span class=\"token keyword\">UNIQUE</span><span class=\"token punctuation\">,</span>\n    phone <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>이렇게 테이블을 만들면, SSN은 Candidate key 가 되고, 해당 attribute에는 null을 제외한 중복값을 허락하지 않는다.</p>\n<h2 id=\"check\" style=\"position:relative;\"><a href=\"#check\" aria-label=\"check permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CHECK</h2>\n<p>CHECK 는 어떤 attribute의 Domain을 더 명확하게 특정해주어서 해당 Domain 이 아닌 값이 들어올 수 없게 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span> student <span class=\"token punctuation\">(</span>\n    name <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">NOT</span> <span class=\"token boolean\">NULL</span><span class=\"token punctuation\">,</span>\n    SSN <span class=\"token keyword\">VARCHAR</span> <span class=\"token keyword\">UNIQUE</span><span class=\"token punctuation\">,</span>\n    phone <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    nationality <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">CHECK</span> <span class=\"token punctuation\">(</span>nationality <span class=\"token operator\">IN</span> <span class=\"token punctuation\">(</span><span class=\"token string\">'Korea'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'China'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Japan'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>이렇게 테이블을 만들면 nationality attribute 에 대해서는 모든 tuple이 Korea, China, Japan 세 값 중에 하나를 가지고 있어야 하고, 그 이외의 다른 값들은 모두 거절된다.</p>\n<h1 id=\"referential-integrity\" style=\"position:relative;\"><a href=\"#referential-integrity\" aria-label=\"referential integrity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Referential Integrity</h1>\n<p>여러 테이블을 관계시키거나 함께 사용할 때, 우리는 Foreign Key 를 사용하게 된다. Foreign Key의 정의는 다음과 같이 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span> student <span class=\"token punctuation\">(</span>\n    name <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">NOT</span> <span class=\"token boolean\">NULL</span><span class=\"token punctuation\">,</span>\n    SSN <span class=\"token keyword\">VARCHAR</span> <span class=\"token keyword\">UNIQUE</span><span class=\"token punctuation\">,</span>\n    phone <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    nationality <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">CHECK</span> <span class=\"token punctuation\">(</span>nationality <span class=\"token operator\">IN</span> <span class=\"token punctuation\">(</span><span class=\"token string\">'Korea'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'China'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Japan'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">FOREIGN</span> <span class=\"token keyword\">KEY</span> <span class=\"token punctuation\">(</span>SSN<span class=\"token punctuation\">)</span> <span class=\"token keyword\">REFERENCES</span> Korea\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>위와 같이 테이블을 만들게 되면, student 테이블에 있는 SSN 이라는 attribute는 Foreign Key 가 되어서 Korea 테이블에 있는 동일한 이름의 attribute를 참조하게 된다. 즉, student 테이블의 SSN이라는 값은 항상 Korea 테이블에 있는 SSN 컬럼에 존재해야한다.</p>\n<h2 id=\"on-deleteupdate-cascade\" style=\"position:relative;\"><a href=\"#on-deleteupdate-cascade\" aria-label=\"on deleteupdate cascade permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>ON DELETE/UPDATE CASCADE</h2>\n<p>Foreign key 를 생성하면서 데이터 무결성을 위해 위화 같은 조건을 추가해줄 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"sql\"><pre class=\"language-sql\"><code class=\"language-sql\"><span class=\"token keyword\">CREATE</span> <span class=\"token keyword\">TABLE</span> student <span class=\"token punctuation\">(</span>\n    name <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">NOT</span> <span class=\"token boolean\">NULL</span><span class=\"token punctuation\">,</span>\n    SSN <span class=\"token keyword\">VARCHAR</span> <span class=\"token keyword\">UNIQUE</span><span class=\"token punctuation\">,</span>\n    phone <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    nationality <span class=\"token keyword\">VARCHAR</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">CHECK</span> <span class=\"token punctuation\">(</span>nationality <span class=\"token operator\">IN</span> <span class=\"token punctuation\">(</span><span class=\"token string\">'Korea'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'China'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Japan'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">FOREIGN</span> <span class=\"token keyword\">KEY</span> <span class=\"token punctuation\">(</span>SSN<span class=\"token punctuation\">)</span> <span class=\"token keyword\">REFERENCES</span> Korea\n        <span class=\"token keyword\">ON</span> <span class=\"token keyword\">DELETE</span> <span class=\"token keyword\">CASCADE</span>\n        <span class=\"token keyword\">ON</span> <span class=\"token keyword\">UPDATE</span> <span class=\"token keyword\">CASCADE</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>위 예시에서 만들었던 테이블에 CASCADE 를 추가해주었다. 이렇게 만들어진 student 테이블의 SSN 값은 Korean 테이블의 SSN 값을 참조하고 있다.</p>\n<p>그런데 만약 Korea 테이블의 SSN 에 있던 값 중에 하나가 삭제되었다고 해보자. 이렇게 되면 참조의 대상이 되는 Korea 테아블에서는 해당 데이터가 없어졌는데, 참조하는 student 테이블에는 데이터가 남아있을 수도 있는 상황이 생긴다. Foreign Key 의 값이 항상 참조의 대상이 되는 attribute에 있어야 한다는 조건이 깨지는 것이다.</p>\n<p>따라서 DELETE CASCADE 조건을 추가해주면, Korea 테이블에서 참조받는 값을 가진 tuple이 삭제되었을 때, 자동으로 student 테이블에 있는 해당 값을 가진 tuple을 함께 삭제해주게 된다.</p>\n<p>비슷한 맥학으로 UPDATE CASCADE 조건을 추가하게 되면, 참조받는 테이블에 있는 값이 새로운 값으로 갱신될 때, 참조를 하고있는 student 테이블에 있는 값도 함께 갱신된다.</p>\n<p>이렇게 하면 데이터 무결성을 유지할 수 있을 것이다.</p>\n<h2 id=\"self-referencing-table-issue\" style=\"position:relative;\"><a href=\"#self-referencing-table-issue\" aria-label=\"self referencing table issue permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Self Referencing Table Issue</h2>\n<p>어떤 테이블은 자기 자신을 참조하고 있을 수도 있다. 이 경우에는 새로운 tuple 들을 테이블에 넣는 것이 데이터 무결성을 쉽게 꺠뜨릴 수도 있다. 이런 시나리오에서는 다음과 같은 작업을 수행함으로 데이터 무결성을 유지할 수 있다.</p>\n<ol>\n<li>참조할 데이터가 이미 존재하도록 한다.</li>\n<li>모든 foreign key 데이터를 null 로 초기화해두고 모든 tuple을 삽입한 이후에 업데이트한다.</li>\n<li>Foreign key가 없는 상태로 테이블을 만들고 Foreign key 를 나중에 지정해준다.</li>\n</ol>","frontmatter":{"title":"[데이터베이스] 데이터 무결성(Integrity Constraints)","date":"April 17, 2020"}}},"pageContext":{"slug":"/Database/2020-04-17-데이터베이스-데이터무결성/","previous":{"fields":{"slug":"/Operating-Systems/2020-04-17-운영체제-스레드라이브러리/"},"frontmatter":{"title":"[운영체제] 스레드 라이브러리와 스레딩 이슈들(Thread Libraies dand Threading Issues)","category":"Operating-Systems","draft":false}},"next":{"fields":{"slug":"/Database/2020-04-18-데이터베이스-뷰-Views/"},"frontmatter":{"title":"[데이터베이스] 뷰(Views)","category":"Database","draft":false}}}},"staticQueryHashes":["2486386679","3128451518"]}