내가 작업하는 하나의 웹 응용 프로그램 내에서 모든 데이터베이스 작업은 Entity Framework ORM에 정의 된 일부 일반 리포지토리를 사용하여 추상화됩니다.
그러나 일반 리포지토리를 단순하게 디자인하려면 관련된 모든 테이블이 고유 정수 ( Int32
C #, int
SQL)를 정의해야합니다 . 지금까지는 항상 테이블의 PK였으며 또한 IDENTITY
.
외래 키가 많이 사용되며 이러한 정수 열을 참조합니다. 일관성과 ORM에 의한 탐색 특성 생성에 필요합니다.
응용 프로그램 계층은 일반적으로 다음 작업을 수행합니다.
- 테이블에서 초기 데이터로드 (*)-
SELECT * FROM table
- 업데이트 -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- 삭제 -
DELETE FROM table WHERE Id = IdVal
- 삽입 -
INSERT INTO table (cols) VALUES (...)
덜 빈번한 작업 :
- 대량 삽입 -
BULK INSERT ... into table
생성 된 식별자를 검색하기 위해 모든 데이터로드가 뒤 따름 (*) - 대량 삭제 -이것은 일반적인 삭제 작업이지만 ORM의 관점에서 "대량"입니다.
DELETE FROM table where OtherThanIdCol = SomeValue
- 대량 업데이트 -이것은 일반적인 업데이트 작업이지만 ORM의 관점에서 볼 때 "대량"입니다.
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* 모든 작은 테이블은 응용 프로그램 수준에서 캐시되며 거의 모든 SELECTs
데이터베이스에 도달하지 않습니다. 전형적인 패턴은 초기 하중과 많은 INSERT
s, UPDATE
s 및 DELETE
s입니다.
현재 응용 프로그램 사용을 기반으로 테이블에서 100M 레코드에 도달 할 가능성은 매우 적습니다.
질문 : DBA의 관점에서이 테이블 디자인 제한으로 인해 심각한 문제가 발생할 수 있습니까?
[편집하다]
답변 (훌륭한 피드백 감사)과 참조 기사를 읽은 후에 더 자세한 내용을 추가해야한다고 생각합니다.
현재 응용 프로그램 사양 -모델을 다른 응용 프로그램에서도 재사용 할 수 있는지 이해하고 싶기 때문에 현재 웹 응용 프로그램에 대해서는 언급하지 않았습니다. 그러나 필자의 특별한 경우는 DWH에서 많은 메타 데이터를 추출하는 응용 프로그램입니다. 소스 데이터가 매우 지저분하고 (이상한 방식으로 비정규 화되어 일부 불일치가 발생하고 많은 경우 자연 식별자가 없음) 내 앱이 명확하게 분리 된 엔티티를 생성합니다. 또한 생성 된 많은 식별자 (
IDENTITY
)가 표시되므로 사용자가이를 비즈니스 키로 사용할 수 있습니다. 대규모 코드 리팩토링 외에도 GUID 사용을 제외합니다 ."행을 고유하게 식별 할 수있는 유일한 방법이되어서는 안됩니다" (Aaron Bertrand ♦)-이는 매우 좋은 조언입니다. 내 모든 테이블은 비즈니스 중복이 허용되지 않도록 UNIQUE CONSTRAINT도 정의합니다.
프런트 엔드 앱 중심 디자인과 데이터베이스 중심 디자인 -디자인 선택은 이러한 요인에 의해 발생합니다
Entity Framework 제한 사항 -여러 열 PK가 허용되지만 해당 값을 업데이트 할 수 없습니다
사용자 지정 제한 -단일 정수 키를 사용하면 데이터 구조와 비 SQL 코드가 크게 단순화됩니다. 예 : 모든 값 목록에는 정수 키와 표시된 값이 있습니다. 더 중요한 것은 캐싱으로 표시된 모든 테이블이
Unique int key -> value
맵 에 배치 될 수 있음을 보장합니다 .
복잡한 선택 쿼리 -모든 작은 (<20-30K 레코드) 테이블 데이터가 응용 프로그램 수준에서 캐시되므로 거의 발생하지 않습니다. 이로 인해 애플리케이션 코드를 작성할 때 (LINQ를 작성하기가 더 어려워) 인생이 조금 어려워 지지만 데이터베이스는 훨씬 더 훌륭합니다.
목록보기 -
SELECT
로드시 (모든 것이 캐시 됨) 또는 다음과 같은 쿼리를 생성하지 않습니다 .SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
다른 모든 필수 값은 캐시 조회 (O (1))를 통해 페치되므로 복잡한 쿼리가 생성되지 않습니다.
뷰 편집 -
SELECT
다음과 같은 명령문 이 생성됩니다 .SELECT allcolumns FROM BigTable WHERE PKId = value1
(모든 필터와 값은 int
s입니다)