[MySQL] 외래키(FOREIGN KEY)의 정의 무결성 제약조건 > 리눅스서버
리눅스서버

[MySQL] 외래키(FOREIGN KEY)의 정의 무결성 제약조건

조회 454회 댓글 0건

왜래키는 잘 쓰면 보약이고 잘못하면 관련된 테이블 모두 확인 하느라 부하가 심해진다.

그래서 무조건 쓰지 못하게 하는곳도 있는 실정이다. 사실 우리가 그런부분이 있다.

사이트의 부하가 많지 않다면 사용하는것을 권장 하는데 문제가 될일이 별로 없기 때문에 그렇다.


[MySQL] 외래키(FOREIGN KEY)의 정의 무결성 제약조건
 


외래키는 두 테이블 간의 관계를 정의하는 데 사용 되는 것으로 보통 부모 테이블과 자식 테이블 간의 관계를 나타내는 데에 사용됩니다.

1. 관계 정의 

 외래키는 부모 테이블의 기본 키(primary key) 또는 유일한 키(unique key)와 연결됩니다. 이 관계를 통해 자식 테이블의 행들이 부모 테이블의 행들을 참조할 수 있습니다.


2. 무결성 유지

 외래키 제약 조건을 사용하여 데이터 무결성을 유지할 수 있습니다. 이는 자식 테이블에 존재하는 값이 부모 테이블에 있는 값과 일치해야 한다는 것을 의미합니다. 이를 통해 부모 테이블에서 삭제되거나 변경된 행에 대한 적절한 처리가 이루어질 수 있습니다.


3. 참조 무결성 제약 조건

 MySQL에서 외래키를 정의할 때 ON DELETE 및 ON UPDATE와 같은 옵션을 사용하여 부모 테이블에서 행이 삭제되거나 업데이트 될 때의 동작을 정의할 수 있습니다. 예를 들어 부모 테이블에서 행이 삭제될 때 자식 테이블에서 해당 행에 대한 참조를 자동으로 삭제하도록 설정할 수 있습니다.


4. 인덱스 생성

 MySQL에서 외래키를 정의하면 해당 열에 대한 인덱스가 자동으로 생성됩니다. 이는 외래키 관련 작업의 성능을 향상시키는 데 도움이 됩니다.


5. 제약 조건

 외래키 제약 조건을 사용하여 특정 작업이 수행되기 전에 조건을 검증할 수 있습니다. 예를 들어 외래키 제약 조건을 사용하여 부모 테이블에 존재하지 않는 값을 자식 테이블에 삽입하는 것을 방지할 수 있습니다.


요약하자면 MySQL의 외래키는 데이터베이스에서 데이터의 일관성과 무결성을 유지하기 위한 중요한 기능 중 하나입니다.



  -- 주문 테이블 생성
  CREATE TABLE Orders (
      OrderID INT PRIMARY KEY,
      CustomerID INT,
      OrderDate DATE,
      TotalAmount DECIMAL(10, 2),
      FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID)
  );

  -- 고객 테이블 생성
  CREATE TABLE Customer (
      CustomerID INT PRIMARY KEY,
      FirstName VARCHAR(50),
      LastName VARCHAR(50),
      Email VARCHAR(100)
  );

  -- 주문과 고객 정보를 함께 조회하는 SQL
  SELECT Orders.OrderID, Orders.OrderDate, Orders.TotalAmount, Customer.FirstName, Customer.LastName
  FROM Orders
  JOIN Customer ON Orders.CustomerID = Customer.CustomerID;

  mysql> desc Customer;
  +------------+--------------+------+-----+---------+-------+
  | Field      | Type         | Null | Key | Default | Extra |
  +------------+--------------+------+-----+---------+-------+
  | CustomerID | int          | NO   | PRI | NULL    |       |
  | FirstName  | varchar(50)  | YES  |     | NULL    |       |
  | LastName   | varchar(50)  | YES  |     | NULL    |       |
  | Email      | varchar(100) | YES  |     | NULL    |       |
  +------------+--------------+------+-----+---------+-------+
  4 rows in set (0.01 sec)

  mysql> desc Orders; select * from Orders;
  +-------------+---------------+------+-----+---------+-------+
  | Field       | Type          | Null | Key | Default | Extra |
  +-------------+---------------+------+-----+---------+-------+
  | OrderID     | int           | NO   | PRI | NULL    |       |
  | CustomerID  | int           | YES  | MUL | NULL    |       |
  | OrderDate   | date          | YES  |     | NULL    |       |
  | TotalAmount | decimal(10,2) | YES  |     | NULL    |       |
  +-------------+---------------+------+-----+---------+-------+
  4 rows in set (0.00 sec)


  mysql> desc SELECT Orders.OrderID, Orders.OrderDate, Orders.TotalAmount, Customer.FirstName, Customer.LastName FROM Orders JOIN Customer ON Orders.CustomerID = Customer.CustomerID;
  +----+-------------+----------+------------+--------+---------------+---------+---------+-------------------------+------+----------+-------------+
  | id | select_type | table    | partitions | type   | possible_keys | key     | key_len | ref                     | rows | filtered | Extra       |
  +----+-------------+----------+------------+--------+---------------+---------+---------+-------------------------+------+----------+-------------+
  |  1 | SIMPLE      | Orders   | NULL       | ALL    | CustomerID    | NULL    | NULL    | NULL                    |   10 |   100.00 | Using where |
  |  1 | SIMPLE      | Customer | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | test1.Orders.CustomerID |    1 |   100.00 | NULL        |
  +----+-------------+----------+------------+--------+---------------+---------+---------+-------------------------+------+----------+-------------+
  2 rows in set, 1 warning (0.00 sec)


  -- 오류가 발생 한다.
  mysql> delete from Customer where CustomerID IN (1,3,5,7);
  ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails ("test1"."Orders", CONSTRAINT "Orders_ibfk_1" FOREIGN KEY ("CustomerID") REFERENCES "Customer" ("CustomerID"))

  -- 확인을 테이블 생성된것을 보고 해야 한다. show index from Orders; 을 보고 하면 안된다.
  mysql> SHOW CREATE TABLE Orders;
  CREATE TABLE "Orders" (
    "OrderID" int NOT NULL,
    "CustomerID" int DEFAULT NULL,
    "OrderDate" date DEFAULT NULL,
    "TotalAmount" decimal(10,2) DEFAULT NULL,
    PRIMARY KEY ("OrderID"),
    KEY "CustomerID" ("CustomerID"),
    CONSTRAINT "Orders_ibfk_1" FOREIGN KEY ("CustomerID") REFERENCES "Customer" ("CustomerID")
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

  -- 외래키를 삭제 해준다.
  mysql> ALTER TABLE Orders DROP FOREIGN KEY Orders_ibfk_1;
  Query OK, 0 rows affected (0.02 sec)
  Records: 0  Duplicates: 0  Warnings: 0

  -- 다시 생성하고 확인 한다.
  mysql> ALTER TABLE Orders ADD CONSTRAINT CustomerID FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID) ON DELETE CASCADE;
  Query OK, 10 rows affected (0.04 sec)
  Records: 10  Duplicates: 0  Warnings:0

  -- 또는 업데이트도 가능하게 해준다.
  ALTER TABLE Orders ADD CONSTRAINT CustomerID FOREIGN KEY (CustomerID) REFERENCES Customer(CustomerID) ON DELETE CASCADE ON UPDATE CASCADE;

  mysql> SHOW CREATE TABLE Orders;
  CREATE TABLE "Orders" (
    "OrderID" int NOT NULL,
    "CustomerID" int DEFAULT NULL,
    "OrderDate" date DEFAULT NULL,
    "TotalAmount" decimal(10,2) DEFAULT NULL,
    PRIMARY KEY ("OrderID"),
    KEY "CustomerID" ("CustomerID"),
    CONSTRAINT "CustomerID" FOREIGN KEY ("CustomerID") REFERENCES "Customer" ("CustomerID") ON DELETE CASCADE
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |

  -- 같이 삭제 되었는지 확인해 본다.
  mysql> delete from Customer where CustomerID IN (1,3,5,7);
  Query OK, 4 rows affected (0.01 sec)

  mysql> select * from Orders;
  +---------+------------+------------+-------------+
  | OrderID | CustomerID | OrderDate  | TotalAmount |
  +---------+------------+------------+-------------+
  |       2 |          2 | 2024-04-12 |      150.00 |
  |       4 |          4 | 2024-04-11 |      120.00 |
  |       6 |          6 | 2024-04-10 |      300.00 |
  |       8 |          8 | 2024-04-09 |      180.00 |
  |       9 |          9 | 2024-04-08 |      250.00 |
  |      10 |         10 | 2024-04-08 |      130.00 |
  +---------+------------+------------+-------------+

  -- 관계가 있으면 드랍도 안된다.
  mysql> drop table Customer;
  ERROR 3730 (HY000): Cannot drop table 'Customer' referenced by a foreign key constraint 'CustomerID' on table 'Orders'.




  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
전체 168건 1 페이지
  • profile_image 누군가 이 사이트에 불필요한 링크를 걸었습니다.그런데 희안 한것은 작동도 안되는 것을 링크를 걸었다는 것입니다.이 문제로 인해 불필요한 리소스가 들어가는것과 웹봇도 불필요한것을 수집하여 접근 하기 때문에 양쪽에 문제가 있는 것입니다.검색을 통해 원인이 되는 웹사이트를 잡으려 생각 하고 있습니다. 형태는 아래와 같습니다. SQL 인젝션은 아닌데 다른 주소로 넘어가도록 우회 시키려 한것 같은데 이렇게 링크 걸 때 확인도 안하고 링크를 걸었을까?no 파라미터는 프로그램을 보면 숫자가 아니면 작동하지 않도록 되어 있습니다.34.64.82.75 - - [02/Oct/2024:16:35:34 +0900] "GET /content/…
  • profile_image 고객의 서버 시스템을 복구해야 할 때 사용하는 동의서 입니다. 보안 뿐만이 아니라 급작스러운 일이 있을 수 있기 때문에 백업의 중요성과 예상하지 못한 문제로 인하여 고객에게 사전에 충분히 인지 할 수 있도록 하기 위한 동의서 양식 입니다. ● 시스템 복구 동의 사항   1. 작업비용 산출 및 청구복구 의뢰 접수 후 담당자는 시스템 상태를 파악하며, 예상 작업시간과 비용을 산출 하여 담당 고객에게 처리해야 할 부분을 확인 합니다.시스템 복구에 대한 비용은 작업 시작 전에 청구 됩니다.※ 주간 기본비용 : 0만원/시간, 야간 기본비용 : 0만원/시간   2. 작업의뢰 전에 시스템의 파일을 무조건 모두 백업 받아야 …
  • profile_image http 프로토콜은 사실상 사용하지 않기 때문에 들어오는 그대로 https로 301 처리 합니다.그런데!!하지 말아야할 디렉토리가 발견되어 ssl 이동한 다음 404처리를 하기 때문에 처음 부터 404 처리 하는것이 좋은 경우가 있습니다.   <VirtualHost *:80>    ServerName pabburi.co.kr    DocumentRoot "/www_html"    RewriteEngine on    # Return 404 for any requests to the /data/ directory    RewriteRule ^/data/.* - [R=404,L]    # https 301    R…
  • profile_image 간혹 파일을 찾기는 해야 하는데 언제쯤 이후에 만든것은 확실한데 어디 있는지 모르는 경우가 있을 때 유용 합니다.아래는 php 확장자인 경우 예를 들었습니다.삼바 연결된 곳이라면 PC 문서를 찾는데 무척 좋습니다.find . -type f -name "*.php" -newermt 2024-03-01 ▷ 각 항목에 대한 설명find: 파일 검색 명령어..: 현재 디렉토리를 의미.-type f: 파일만 검색.-name "*.php": .php 확장자를 가진 파일만 검색.-newermt 2024-03-01: 2024년 3월 1일 이후에 수정된 파일 검색.▶ find 명령으로 파일에 특정 문자가 있는 경우만 출력   아래는 현…
  • profile_image ftp는 vsftpd 별도로 사용하고 있는데 오늘 보니 사용하지 않는 21번 포트가 열려 있네요.전 디폴트 포트는 사용하지 않기 때문에 이런게 있으면 안되지요~netstat -antp | grep LISTEN확인하니 xinetd 에서 띄워져 있네요.vim /etc/xinetd.d/vsftpd 파일을 열면 아래와 같은 텍스트를 볼 수 있는데요.  service ftp  {          socket_type             = stream          wait                    = no          user                    = root          server      …
  • profile_image MySQL에서 트리거(trigger)는 특정 테이블에 대해 INSERT UPDATE DELETE와 같은 DML(데이터 조작 언어) 작업이 수행될 때 자동으로 실행되는 프로시저입니다. 트리거는 데이터의 무결성을 유지하거나 로깅 감사 등의 목적으로 사용될 수 있습니다. 트리거는 데이터베이스가 특정 조건에 반응하여 자동으로 특정 작업을 수행하도록 할 때 유용합니다.▷ 트리거의 주요 특징- 자동 실행: 트리거는 관련 테이블에 특정 DML 작업이 수행될 때 자동으로 실행됩니다.- 데이터 무결성 보장: 데이터의 무결성을 보장하기 위해 사용될 수 있으며 복잡한 제약 조건을 구현하는 데 유용합니다.- 감사 및 로깅: 데이터 변경 사항…