복붙노트

[SQL] 어떻게 사람의 여러 일을 만들 수 있습니다

SQL

어떻게 사람의 여러 일을 만들 수 있습니다

나는 많은 테이블로 설정 데이터베이스를 가지고 있고 그것을 하나의 비트에서 떨어져 모든 보이는 좋은 ...

Inventory Table <*-----1> Storage Table <1-----1> Van Table
                              ^
                              1
                              |-------1> Warehouse Table

스토리지 테이블은 밴 및 창고 테이블부터 비슷 사용되지만 어떻게 보관 및 창고 / 반 테이블 간의 관계를 만들려면 어떻게해야합니까? 스토리지 오브젝트는 1 개 저장 장소와 종류를 할 수있는 그들이 1 일을해야 의미가있다. 나는 StorageId 기본 키에 밴 / 창고 테이블 링크가 다음 반 및 창고 테이블이 같은 StorageId을 해달라고 있는지 확인하는 제약 조건을 추가 할 수 있지만 그것은 더 나은 방법을 수행 할 수 있었던 것처럼이 보인다 않았다.

나는이 일을 여러 가지 방법으로 볼 수 있지만 그들은 모두 도움이 좋은 것, 그래서 잘못된 것!

해결법

  1. ==============================

    1.당신은 (또한 "서브 클래스"또는 "카테고리」로서 개체 - 관계 모델링에 알려진) 상속을 사용하고 있습니다. 일반적으로, 데이터베이스에 표현하는 3 가지 방법이 있습니다 :

    당신은 (또한 "서브 클래스"또는 "카테고리」로서 개체 - 관계 모델링에 알려진) 상속을 사용하고 있습니다. 일반적으로, 데이터베이스에 표현하는 3 가지 방법이 있습니다 :

    나는 보통 3 접근법을 선호하지만, 존재와 응용 프로그램 수준에서 아이의 독점을 모두 적용합니다. 데이터베이스 수준에서 모두 시행하는 것은 조금 복잡하지만, DBMS가 지원하는 제약을 연기하는 경우 수행 할 수 있습니다. 예를 들면 :

    CHECK (
        (
            (VAN_ID IS NOT NULL AND VAN_ID = STORAGE_ID)
            AND WAREHOUSE_ID IS NULL
        )
        OR (
            VAN_ID IS NULL
            AND (WAREHOUSE_ID IS NOT NULL AND WAREHOUSE_ID = STORAGE_ID)
        )
    )
    

    이 아이의 (인해 CHECK 및 FK1 / FK2의 조합) (수표에 의한) 독점과 존재에 모두 적용됩니다.

    불행하게도, MS SQL 서버는 이연 제약 조건을 지원하지 않습니다,하지만 당신은 저장 프로 시저 뒤에 전체 동작을 "숨기기"할 수 있어야하고, 테이블을 직접 수정하는 고객을 금지 할 수 있습니다.

    그냥 독점은 이연 제약없이 적용 할 수 있습니다 :

    STORAGE_TYPE (0과 1이 응용 프로그램에 "알려진"하고 그에 따라 해석, 위의 예에서) 타입 판별, 공간에 저장하기 일반적으로 정수입니다.

    VAN.STORAGE_TYPE 및 WAREHOUSE.STORAGE_TYPE 스토리지를 저장하고 검사의 필요성을 피하기 위해 (일명. "계산") 열을 계산 할 수있다.

    --- 편집하다 ---

    계산 된 열은 다음과 같이 SQL 서버에서 작동합니다 :

    CREATE TABLE STORAGE (
        STORAGE_ID int PRIMARY KEY,
        STORAGE_TYPE tinyint NOT NULL,
        UNIQUE (STORAGE_ID, STORAGE_TYPE)
    );
    
    CREATE TABLE VAN (
        STORAGE_ID int PRIMARY KEY,
        STORAGE_TYPE AS CAST(0 as tinyint) PERSISTED,
        FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
    );
    
    CREATE TABLE WAREHOUSE (
        STORAGE_ID int PRIMARY KEY,
        STORAGE_TYPE AS CAST(1 as tinyint) PERSISTED,
        FOREIGN KEY (STORAGE_ID, STORAGE_TYPE) REFERENCES STORAGE(STORAGE_ID, STORAGE_TYPE)
    );
    
    -- We can make a new van.
    INSERT INTO STORAGE VALUES (100, 0);
    INSERT INTO VAN VALUES (100);
    
    -- But we cannot make it a warehouse too.
    INSERT INTO WAREHOUSE VALUES (100);
    -- Msg 547, Level 16, State 0, Line 24
    -- The INSERT statement conflicted with the FOREIGN KEY constraint "FK__WAREHOUSE__695C9DA1". The conflict occurred in database "master", table "dbo.STORAGE".
    

    불행하게도, SQL 서버는 유지해야하는 외래 키에 사용되는 계산 열을 위해 필요합니다. 다른 데이터베이스는 일부 저장 공간을 절약 할 수 있습니다이 제한 (예를 들어 오라클의 가상 열)이 없을 수 있습니다.

  2. ==============================

    2.당신이 말하는 것처럼, 많은 솔루션이 있습니다. 나는 그 성능이나 저장이 문제가되기 나중에 경우 최적화, 가장 간단한 솔루션으로 시작하는 추천 할 것입니다. 가장 간단한 해결책은 (그러나 최적의 스토리지 측면에서) 스토리지 유형의 열 (행이 밴 또는 창고를 나타내는 지 여부를 나타내는)가 스토리지 테이블이하는 것, 플러스 밴에 대한 열뿐만 아니라 창고 속성으로 속성. 밴을 나타내는 행에서웨어 하우스 속성의 열이 모두 null가됩니다. 창고를 나타내는 행에서 반 속성의 열이 모두 null가됩니다.

    당신이 말하는 것처럼, 많은 솔루션이 있습니다. 나는 그 성능이나 저장이 문제가되기 나중에 경우 최적화, 가장 간단한 솔루션으로 시작하는 추천 할 것입니다. 가장 간단한 해결책은 (그러나 최적의 스토리지 측면에서) 스토리지 유형의 열 (행이 밴 또는 창고를 나타내는 지 여부를 나타내는)가 스토리지 테이블이하는 것, 플러스 밴에 대한 열뿐만 아니라 창고 속성으로 속성. 밴을 나타내는 행에서웨어 하우스 속성의 열이 모두 null가됩니다. 창고를 나타내는 행에서 반 속성의 열이 모두 null가됩니다.

    그런 식으로, 당신은 테이블의 수를 줄이려고하고 쿼리의 좋은 간단한 유지. 저장 꽉 될 경우 당신의 결정을 다시 방문 할 수 있도록 준비.

  3. ==============================

    3.어떻게 든 나는 이런 식으로 뭔가 함께 갈 것 때문에 재고 항목, 위치를 변경할 수 있다는 것을 나에게 보인다.

    어떻게 든 나는 이런 식으로 뭔가 함께 갈 것 때문에 재고 항목, 위치를 변경할 수 있다는 것을 나에게 보인다.

  4. from https://stackoverflow.com/questions/9174200/how-to-create-multiple-one-to-ones by cc-by-sa and MIT license