2015-02-04 2 views
1

SQL Server 2012를 데이터베이스로 사용하는 클라이언트 - 서버 시스템이 있습니다. 시스템은 정기적으로 업데이트되고 향상됩니다.SQL Server에서 일반 테이블 만들기

우리는 최근 테이블 디자인의 반복적 인 패턴을 보았습니다. 사용자 테이블을 데이터베이스의 다른 테이블에 연결하여보기 및 권한의 기초를 형성하는 테이블입니다. 예 :

CREATE TABLE Documents_Users (
    ID int not null identity(1,1) not for replication, 
    UserID int not null, -- foreign key to the Users table 
    DocumentID int not null, --- foreign key to the Documents table 
    [...] 
) 

우리는 대신이 모든 테이블을 만드는, 우리는이 같은 하나 개의 큰 테이블을 만들 수 있다고 생각했다 :

CREATE TABLE UserPermissions (
    ID int not null identity(1,1) not for replication, 
    UserID int not null, -- foreign key to the Users table 
    ObjectID int not null, -- pointer to any object ID in another table 
    TableID int not null, -- actual id of the referenced table in sys.objects 
    [...] 
) 

장점 : 하나 개의 테이블이 해결하는 우리의 권한 모두가 모든 필요를 현재와 ​​미래의 테이블.

단점 :

  1. 없는 외래 키. 우리는 한 번씩 실행되는 작업을 생성하고 고아 포인터를 삭제해야합니다 (스토어드 프로 시저에서 삭제하지 않는 경우).

  2. 뷰의 라인을 따라 쿼리 할 필요

    선택 * some_table]에서 ID 곳에서 ( 가 UserPermissions에서 OBJECTID 선택 여기서 테이블 ID = OBJECT_ID ('someTableName') )

이런 일반화를 만들려면 그만한 가치가 있으며 좋은 습관이 필요합니까? 가능한 한 많은 테이블이 아닌 하나의 테이블과 하나의 인덱스를 읽으면 성능이 향상됩니까?

+0

ERP에는 이와 같은 일반화 된 테이블이 많이 있습니다 (예 : 특성 테이블, 특성은 테이블의 모든 개체와 관련 될 수 있음). 장점 - 적은 테이블 (여전히 수백 개의 테이블이 있음), Attributes 테이블의 공통 트리거. 외래 키 대신 일반 테이블에서 INSERT UPDATE 트리거를 사용하여 모든 대상 테이블의 키 무결성을 검사해야하며 대상 테이블에서 DELETE 트리거를 사용하여 공통 테이블에서 삭제하거나 부모 삭제를 방지해야합니다. – huhu78

+1

SQL Server sys 테이블 식별자 (예 : TableId)의 값을 유지하지 마십시오. 이러한 핵심 가치는 본질적으로 취약하고 여러 가지 이유로 변경 될 수 있습니다. 그들에게 의지하면 당신에게 많은 고통을 줄 수 있습니다. 객체 이름을 사용하거나 자체 대리 문자를 만듭니다. 당신의 쿼리는 분명히 조인을 단순화합니다 : SELECT s. * FROM [some_table] s, UserPermissions u WHERE s.ID = u.ObjectID 및 u.name = 'some_table'; 원칙적으로 동일한 SEQUENCE 객체를 사용하여 IDENTITY 대신 모든 ObjectiD를 생성하면 여기에 외래 키를 사용할 수 있습니다. – sqlvogel

+0

@sqlvogel -이 의견에 감사드립니다. 나는 이것을 몰랐다. – user884248

답변

0

저는 지금 당장 같은 선택에 직면하고 있습니다. 제 생각에는 일반 솔루션을 사용할 것입니다. 나는 의미론이 덜 명확하기 때문에 제네릭 솔루션의 팬이 아니며, 당신이 그것을 알기도 전에, 당신은 이해하기 어려운 혼란에 빠져 있습니다. 그러나 여기에서는 로깅, 언어 및 보안과 같은 도메인 전반에 걸친 명확하게 정의 된 목적을 제공하는 것이 허용되는 것으로 생각하는 경향이 있습니다.

이의 제기에 대해 삭제 된 고아가 어떤 방식으로도 존재하지 않는다고 생각합니다. 따라서 한 번 청소를 시작하면 좋은 해결책이 될 것입니다. 쿼리에 관해서는 인라인 테이블 값 함수, 일명 매개 ​​변수화 된 뷰 (각 테이블에 대한 뷰 대신)를 사용하여 UserId를 인수로 사용합니다. 선택적으로 테이블 자체에 대한 읽기 권한을 제한하고 뷰에 대한 권한 만 허용 할 수 있습니다.

퍼포먼스 향상은 한계가있을 것이라고 생각하지만 일반적인 솔루션에서는 여전히 더 좋습니다. 나를위한 주된 이유는 덜 어수선한 다이어그램이 될 것입니다.

2

내 직감은 아마도별로 좋은 생각이 아닐 수 있습니다.

  • 다음 기본 테이블에서 다른 테이블을 "상속"기본 테이블에

    • 연결 사용자 :

      더 나은 대안은 상속 1을 사용하는 것입니다.2

    추가 모든 미래 테이블, 당신은 단지 기존의 기본 테이블에서 상속 할 수 있으며 자동으로 이미 구현 한 보안 논리 "에 연결"됩니다.

    우리는 현재 가치있는 부분에 대해 이러한 아키텍처를 기반으로 강력한 보안 메커니즘을 구현하고 있으며 현재까지 잘 작동합니다.


    또한 같은 ER 모델링에 알려진 1 : "카테고리"또는 "일반화 계층 구조"또는 "등의 서브 클래스"

    불행하게도 2, 상속 직접 관계에서 지원되지 않습니다 (PostgreSQL조차도 부분적으로 구현하는 것조차도 아니다.) 그래서 그것을 에뮬레이트 할 필요가있다. (여기에 one example이 있고 this을 읽고 싶을 수도있다.) 이것은 문제를 가져 오지만 특정 시나리오에서는 여전히 유용하다. .

  • +0

    "상속"이란 기본적으로 외래 키가있는 테이블을 원본 "기본"테이블에 추가하는 것을 의미합니다. – user884248

    +0

    가난한 사람의 상속은 [tag : single-table-inheritance] 및 [tag : class-table-inheritance]의 두 태그로 설명됩니다. –

    +0

    @ user884248이 경우 예. 링크를 읽는다면 다른 전략이 실제로 있다는 것을 알 수 있습니다 만,이 경우에 가장 적합한 전략 일 것입니다. –

    0

    사용자 X 권한이 X 유형에 따라 속성을 필요로 할 때 발생합니다. 즉 UserDocumentPermission은 읽기, 쓰기, 삭제, 추가 등을 할 수 있지만 UserCarPermission은 drive, start 및 공원 허가.

    많은 테이블이있는 경우 누가 신경 쓰는지. 기억하기 쉽도록 명명 규칙을 사용할 수 있습니다.

    +0

    감사합니다. @bpeikes. 이것은 우리가 염두에 두었던 문제 중 하나입니다. 우리는 이러한 경우를 위해 외부 테이블을 생성하는 것이 가치가 있는지 또는 너무 많은 테이블의 원래 문제가 다른 방식으로 발생한다는 것을 의미하는 것인지 논쟁 중입니다. – user884248

    관련 문제