2009-02-05 3 views
10

데이터베이스에서 키/값 테이블을 디자인해야하며이를 수행하는 가장 좋은 방법에 대한 지침을 찾고 있습니다. 기본적으로, 명명 된 속성의 동적 집합에 값을 연결하고이를 외부 키에 적용 할 수 있어야합니다. 데이터베이스 테이블의 키/값 쌍

내가 지원할 수 있어야 할 필요가있는 작업

은 다음과 같습니다

  • 열거 현재 활성 키를 모두
  • 이 모든 결정 항목 그룹에 키/값 쌍을 적용 주어진 키에 대한 값을 가진 항목
  • 주어진 키와 연관된 값이 몇 가지 기준과 일치하는 모든 항목을 결정합니다.

은이 작업을 수행하는 가장 간단한 방법은 테이블을 정의하는 것 같다 :

CREATE TABLE KeyValue (
    id int, 
    Key varchar..., 
    Value varchar... 
); 

그것은 내가 어떤 키를 제공하기 때문에 키 열에서 많은 데이터를 복제 될 가능성이 나는 것 같다 많은 수의 문서에 대해 정의 될 수 있습니다. Key varchar를 다른 테이블로 정수 조회로 바꾸면이 문제를 완화하고 (활성 키를 모두 열거하는 것이 훨씬 효율적으로 처리됩니다.) 조회 테이블을 유지 관리하는 문제가 있습니다. 속성을 정의하고 키/값이 지워질 때마다 항목을 제거 할 수 있습니다).

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변

1

탐색 할 가치가있는 옵션은 표에 SHA1 또는 MD5를 삽입하기 전에 키를 소화하는 것입니다.

이렇게하면 조회 테이블을 없앨 수는 있지만 한 방향으로 만 진행되므로 키를 반복 할 수 없습니다.

1

몇 가지 디자인을 선택할 수도 있습니다.

선택 1 : sambo99는 지적 아마도 당신이 수정할 수 :

keys (
id int not null auto_increment 
key string/int 
hash_code int -- this would be computed by the inserting code, so that lookups would effectively have the id, and you can look them up directly 
) 

values (
id int not null auto_increment -- this column might be nice since your hash_codes might colide, and this will make deletes/updates easier 
key_id int -- this column becomes optional 
hash_code int 
value string/varchar/int... 
) 

-

+0

충돌 가능성이 거의 0입니다. 충돌을 일으킬 수있는 슈퍼 악마가 필요합니다. SHA256을 사용할 수 있을지 걱정됩니다. –

+2

DC++에서 개인적으로 해시 충돌 (TTH)을 보았습니다. 불가능하지 않다. – erikkallen

5

당신이

Keys (
id int not null auto_increment 
key string/int 
) 
values (
id int not null auto_increment 
key_id int 
value string/varchar/int 
) 

선택이 당신의 대답에 암시 두 개의 테이블 디자인 그렇지 않으면 최적화하지 마십시오. 키의 평균 길이는 얼마입니까? 이 테이블이 너무 크면 순진한 방식으로 구현하면 서버의 메모리에 모두 들어갈 수 없습니까? 가장 간단한 방법으로 구현하고 성능을 측정 한 다음 성능이 문제 일 때만 다시 구현하는 것이 좋습니다.

성능에 문제가있는 경우 정수 키와 별도의 테이블을 사용하는 것이 일반적입니다 (정수 열에 대한 조인은 일반적으로 가변 길이 문자열 열을 사용하는 JOINS보다 빠릅니다). 그러나 최적화의 첫 번째 규칙은 MEASURE FIRST입니다. 아마 최적화 된 코드가 실제로 더 빠르게 실행되도록하십시오.

+1

+1 단순함. 성능에 미치는 영향이 분명하고 가혹한 경우가 아니면 항상 가장 쉬운 것으로 이동 한 다음 필요에 따라 테스트하고 최적화하십시오. –

30

Entity-Attribute-Value이라는 데이터베이스 모델을 사용하고 있습니다.이것은 관계형 데이터베이스에 키/값 쌍을 저장하는 일반적인 방법이지만 데이터베이스 정규화 및 효율성 측면에서 여러 가지 약점이 있습니다.

예, 나와있는 테이블 디자인이 가장 일반적인 방법입니다. 이 디자인에서는 모든 엔터티의 모든 특성이 KeyValue 테이블에서 고유 한 행을 가져옵니다.

키 그룹/값 쌍을 항목 그룹에 적용 : 그룹의 각 항목에 대해 하나의 행을 추가해야합니다.

INSERT INTO KeyValue (id, key, value) VALUES (101, 'color', 'green'); 
INSERT INTO KeyValue (id, key, value) VALUES (102, 'color', 'green'); 
INSERT INTO KeyValue (id, key, value) VALUES (103, 'color', 'green'); 

또한 매개 변수를 사용하여 INSERT 문을 준비하고 루프, 또는 무엇이든의 항목 아이디의의 숫자를 통해 실행할 수 있습니다.

열거 현재 활성화 된 모든 키 :

SELECT DISTINCT Key FROM KeyValue; 

는 주어진 키 값을 가지고있는 모든 항목을 확인합니다

SELECT id FROM KeyValue WHERE Key = 'color'; 

는 모든 결정 주어진 키와 연관된 값이 몇 가지 기준과 일치하는 항목 :

SELECT id FROM KeyValue WHERE Value = 'green'; 

엔티티 - 속성 - 값의 문제의 일부 은 다음과 같습니다

  • 확인 키를 확인하는 방법은 모든 항목
  • (모든 항목에 대한 몇 가지 키를 의무화 할 수있는 방법에 대해 같은 철자 즉 기존 테이블 디자인에서는 NULL이 아님).
  • 모든 키는 값으로 VARCHAR를 사용해야합니다. 키마다 다른 데이터 유형을 저장할 수 없습니다.
  • 참조 무결성을 사용할 방법이 없습니다. 일부 키 값에만 적용되는 외래 키는 만들 수 없으며 다른 키 값에는 적용되지 않습니다.

기본적으로 Entity-Attribute-Value는 정규화 된 데이터베이스 디자인이 아닙니다.