복붙노트

[SQL] 관계형 데이터베이스에서 키 값 쌍

SQL

관계형 데이터베이스에서 키 값 쌍

누군가가 데이터베이스에 키 - 값 쌍을 저장하는 경험이 있습니까?

나는 이런 유형의 테이블을 사용하고있다 :

CREATE TABLE key_value_pairs ( 
    itemid           varchar(32) NOT NULL,
    itemkey         varchar(32) NOT NULL,
    itemvalue       varchar(32) NOT NULL,
    CONSTRAINT ct_primarykey PRIMARY KEY(itemid,itemkey)
)

그리고 예를 들어 다음과 같은 행이 존재할 수 :

 itemid            itemkey        itemvalue    
 ----------------  -------------  ------------ 
 123               Colour         Red            
 123               Size           Medium             
 123               Fabric         Cotton

이 제도의 문제점은 데이터를 추출하는 데 필요한 SQL 구문은 매우 복잡하다. 그냥 키 / 값 컬럼의 시리즈를 만들기 위해 더 나은 것인가?

CREATE TABLE key_value_pairs ( 
    itemid            varchar(32) NOT NULL,
    itemkey1        varchar(32) NOT NULL,
    itemvalue1      varchar(32) NOT NULL,
    itemkey2        varchar(32) NOT NULL,
    itemvalue2      varchar(32) NOT NULL,
 . . .etc . . .
)

이 쿼리에 쉽고 빠르게 할 수 있지만, 첫 번째 방법의 확장 성을 부족합니다. 어떤 충고?

해결법

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

    1.당신이 당신의 접근 방식에 계속하기 전에, 나는 겸손하게 다시 단계 당신은 정말 "키 - 값 쌍"테이블에 데이터를 저장하려면 고려 건의 할 것입니다. 나는 응용 프로그램을 모르지만 내 경험 때마다 나는 내가 색상 표, 패브릭 테이블과 크기의 테이블을 만들어 낸 바랍니다 이후에, 무슨 일을했던 것으로 나타났습니다.

    당신이 당신의 접근 방식에 계속하기 전에, 나는 겸손하게 다시 단계 당신은 정말 "키 - 값 쌍"테이블에 데이터를 저장하려면 고려 건의 할 것입니다. 나는 응용 프로그램을 모르지만 내 경험 때마다 나는 내가 색상 표, 패브릭 테이블과 크기의 테이블을 만들어 낸 바랍니다 이후에, 무슨 일을했던 것으로 나타났습니다.

    당신은 키 - 값 쌍의 접근 방식을 경우, 데이터베이스는 크기 필드에 색상 ID를 저장하려고 할 때 당신에게 말할 수 없다, 참조 무결성 제약 조건에 대해 생각해

    여러 도메인에 걸쳐 값의 수천 수있는 일반적인 값 대 (10 개) 값을 테이블에 합류의 성능 이점에 대해 생각합니다. 얼마나 유용 키 값에 대한 인덱스는 정말 될 것입니다?

    도메인이 "사용자 정의"할 필요가 있기 때문에 일반적으로 당신이하고있는 일을 뒤에 추론이다. 그 경우라면 심지어 내가 (즉 실현 가능한 접근 방식이지만) 즉석에서 테이블을 만드는 방향으로 당신을 밀어 않을거야.

    그러나 당신이 여러 테이블보다 쉽게 ​​관리 할 수있을 것입니다 생각, 또는 모든 도메인에 대한 포괄적 인 유지 보수 사용자 인터페이스를 구상하고 있기 때문에, 다음 중지하고 정말 열심히 계속하기 전에 생각하기 때문에 당신의 논리는 경우.

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

    2.어딘가에 둘 사이에 떨어지면 다른 해결책이있다. 당신은 키와 값을 xml 유형 열을 사용할 수 있습니다. 당신이 상품 ID 필드를 유지 그래서, 다음과 같은 몇 가지 키 값 쌍에 대해 정의 된 XML을 포함하는 XML 필드가 <항목> <항목 키 = "색상"값 = "빨간색"/> <항목 키 = "xxx는"값 = " ㅋ "/> 당신은 당신의 데이터가 데이터베이스를 이리저리 추출 할 때 다음 당신은 다른 여러 가지 방법으로 XML을 처리 할 수 ​​있습니다. 사용량에 따라. 이것은이 가능 솔루션을 확장 할 수 있습니다.

    어딘가에 둘 사이에 떨어지면 다른 해결책이있다. 당신은 키와 값을 xml 유형 열을 사용할 수 있습니다. 당신이 상품 ID 필드를 유지 그래서, 다음과 같은 몇 가지 키 값 쌍에 대해 정의 된 XML을 포함하는 XML 필드가 <항목> <항목 키 = "색상"값 = "빨간색"/> <항목 키 = "xxx는"값 = " ㅋ "/> 당신은 당신의 데이터가 데이터베이스를 이리저리 추출 할 때 다음 당신은 다른 여러 가지 방법으로 XML을 처리 할 수 ​​있습니다. 사용량에 따라. 이것은이 가능 솔루션을 확장 할 수 있습니다.

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

    3.당신이 정말로 앉아서 모델을 생각하지 않았기 때문에 첫 번째 방법을 사용하는 것이 대부분의 경우입니다. "음, 우리는 키가 아직있을 것입니다 모르겠어요." 일반적으로이 꽤 빈약 한 디자인입니다. 실제로 그들이해야 열, 같은 키를 가진보다 느리게 될 것입니다.

    당신이 정말로 앉아서 모델을 생각하지 않았기 때문에 첫 번째 방법을 사용하는 것이 대부분의 경우입니다. "음, 우리는 키가 아직있을 것입니다 모르겠어요." 일반적으로이 꽤 빈약 한 디자인입니다. 실제로 그들이해야 열, 같은 키를 가진보다 느리게 될 것입니다.

    당신의 ID가 VARCHAR 왜 나는 또한 질문 것입니다.

    나는 일반적으로 당신이 저장되지 않도록 별도의 테이블에있는 키를 갖고 싶어,하지만 당신이 정말로 키 / 값 테이블을 구현해야하는 드문 경우에, 최초의 솔루션은 벌금 키에서 키로으로 VARCHAR입니다 / 값 테이블.

    예를 들어,

    CREATE TABLE valid_keys ( 
        id            NUMBER(10) NOT NULL,
        description   varchar(32) NOT NULL,
        CONSTRAINT pk_valid_keys PRIMARY KEY(id)
    );
    
    CREATE TABLE item_values ( 
        item_id NUMBER(10) NOT NULL,
        key_id  NUMBER(10) NOT NULL,
        item_value VARCHAR2(32) NOT NULL,
        CONSTRAINT pk_item_values PRIMARY KEY(item_id),
        CONSTRAINT fk_item_values_iv FOREIGN KEY (key_id) REFERENCES valid_keys (id)
    );
    

    그런 다음도 너트 가서 어떤 종류의 검사를 허용하는 키에 "TYPE"을 추가 할 수 있습니다.

  4. ==============================

    4.나는 한 번 창구가 금전 작업에서 자신의 활동을 요약 한 것입니다있는 (데이터 입력에 사용) 스프레드 시트의 작성을 목적으로 한 데이터베이스에 키 - 값 쌍을 사용했다. 각 K / V 쌍은 사용자가 금액 입력되는 명명 된 셀을 나타낸다. 이 방법의 주된 이유는 스프레드 시트가 매우 변경 될 수 있었다이다. 새로운 제품과 서비스를 정기적으로 추가 된 (따라서 새로운 세포 등장). 또한, 특정 세포는 특정 상황에서 필요하지 않은 및 삭제 될 수 있습니다.

    나는 한 번 창구가 금전 작업에서 자신의 활동을 요약 한 것입니다있는 (데이터 입력에 사용) 스프레드 시트의 작성을 목적으로 한 데이터베이스에 키 - 값 쌍을 사용했다. 각 K / V 쌍은 사용자가 금액 입력되는 명명 된 셀을 나타낸다. 이 방법의 주된 이유는 스프레드 시트가 매우 변경 될 수 있었다이다. 새로운 제품과 서비스를 정기적으로 추가 된 (따라서 새로운 세포 등장). 또한, 특정 세포는 특정 상황에서 필요하지 않은 및 삭제 될 수 있습니다.

    내가 쓴 응용 프로그램은 다른 테이블로 표시 별도의 섹션 각각에 창구 시트를 중단 않은 응용 프로그램의 재 작성했다. 문제는 여기에 제품과 서비스가 추가 된 것처럼, 스키마 수정이 필요했다이었다. 모든 디자인을 선택하여 같은 다른에 비해 특정 방향을 복용 장점과 단점이있다. 내 재 설계는 확실히 느린 더 빨리 소모 디스크 공간을 수행; 그러나, 분에 추가 할 매우 민첩하고 새로운 제품과 서비스에 허용했다. 노트의 유일한 문제는, 그러나, 디스크 소비했다; 내가 기억하는 다른 두통이 없었다.

    이미 언급 한 바와 같이 사용자가-이 될 수있을 때, 나는 보통 키 - 값 쌍의 접근 방식을 고려하는 이유가있는 속성의 사용자 별 설정을 가지고 자신의 유형을 만들 소유자가-하고자하는 사업. 이러한 상황에서 나는 다음과 같은 결정에왔다.

    이러한 특성 또는 검색하여 데이터를 검색 할 필요가 데이터의 덩어리가 검색되고 나면 응용 프로그램으로 지연 될 수 있습니다이없는 경우, 내가 사용하는 단일 텍스트 필드의 모든 특성 (JSON, YAML, XML 등을 저장하는 것을 권장합니다 ). 이러한 특성으로 데이터를 검색 할 강력한 필요가 있다면, 그것은 지저분한 가져옵니다.

    당신은 하나가 정렬 열이 문자열 정렬 표현으로 실제 값을 변환한다 표 (ID, ITEM_ID, 키, 값, DATA_TYPE, sort_value) "속성"을 만들 수 있습니다. (예 : 날짜 : "2010-12-25 12시 0분 0초"번호 "0000000001") 아니면 데이터 유형별로 별도의 속성 테이블 (예를 들어 string_attributes, date_attributes, number_attributes)를 만들 수 있습니다. 모두에게 많은 장점과 단점 중 접근 : 첫 번째는 간단하다, 두 번째는 빠릅니다. 모두 당신이 못생긴, 복잡한 쿼리를 작성하게됩니다.

  5. ==============================

    5.경험에서, 나는 특정 키가 더 널리 사용 또는 더 자주 조회 할 것이라는 점을 발견했다. 우리는 일반적으로 다음 약간 주 "항목"테이블에서 특정 필드 등을 포함하는 디자인을 해제 정상화했다.

    경험에서, 나는 특정 키가 더 널리 사용 또는 더 자주 조회 할 것이라는 점을 발견했다. 우리는 일반적으로 다음 약간 주 "항목"테이블에서 특정 필드 등을 포함하는 디자인을 해제 정상화했다.

    예를 들면. 모든 항목은 색상이있는 경우, 당신은 당신의 품목 테이블에 색상 열을 추가 할 수 있습니다. 직물 및 크기를 적게 사용할 수 있고, 키 - 값 쌍 테이블의 분리 유지 될 수있다. 당신은 키 - 값 쌍 테이블의 색상을 유지하지만, 성능상의 이점을 얻을 수있는 아이템 테이블의 데이터를 복제 할 수 있습니다.

    분명히 이것은 데이터와 얼마나 유연 당신이되고 키 - 값 쌍을 필요에 따라 달라집니다. 또한 일관되게 위치하지 않을 당신의 속성 데이터가 발생할 수 있습니다. 그러나 드 정상화는 크게 쿼리를 단순화하고 성능을 향상시킬뿐만 아니라 않습니다.

    성능이되고 문제, 쿼리를 단순화 할뿐만 아니라 때 나는 보통 드 정상화를 고려할 것입니다.

  6. ==============================

    6.8.4 PostgreSQL의 지지체는 단일 PostgreSQL의 데이터 필드 내에서 (키, 값) 쌍들의 세트를 저장하기위한 데이터 타입 hstore. 그것의 사용 정보에 대한 http://www.postgresql.org/docs/8.4/static/hstore.html를 참조하십시오. 아주 오래된 질문이다하지만 누군가 도움이 될 생각이 정보를 전달하는 것으로 생각하지만.

    8.4 PostgreSQL의 지지체는 단일 PostgreSQL의 데이터 필드 내에서 (키, 값) 쌍들의 세트를 저장하기위한 데이터 타입 hstore. 그것의 사용 정보에 대한 http://www.postgresql.org/docs/8.4/static/hstore.html를 참조하십시오. 아주 오래된 질문이다하지만 누군가 도움이 될 생각이 정보를 전달하는 것으로 생각하지만.

  7. ==============================

    7.추출 된 데이터에 대한 SQL 첫 번째 디자인에 복잡한해야하는 이유를 이해하지 않습니다. 확실히 항목에 대한 모든 값을 얻으려면, 당신은 그냥 이렇게 :

    추출 된 데이터에 대한 SQL 첫 번째 디자인에 복잡한해야하는 이유를 이해하지 않습니다. 확실히 항목에 대한 모든 값을 얻으려면, 당신은 그냥 이렇게 :

    SELECT itemkey,itemvalue FROM key_value_pairs WHERE itemid='123';
    

    또는 당신은 단지 해당 항목에 대한 하나의 특정 키를 원하는 경우 :

    SELECT itemvalue FROM key_value_pairs WHERE itemid='123' AND itemkey='Fabric';
    

    첫 번째 디자인은 언제든지 쉽게처럼 새로운 키를 추가 할 수있는 유연성을 제공합니다.

  8. ==============================

    8.나는 다음과 같은 테이블을 설계하는 가장 좋은 방법이라고 생각 :

    나는 다음과 같은 테이블을 설계하는 가장 좋은 방법이라고 생각 :

    현저한 점 :

  9. ==============================

    9.첫 번째 방법은 아주 괜찮습니다. 당신이 원하는 데이터를 추출하고 그냥 전화 UDF를 생성 할 수 있습니다.

    첫 번째 방법은 아주 괜찮습니다. 당신이 원하는 데이터를 추출하고 그냥 전화 UDF를 생성 할 수 있습니다.

  10. ==============================

    10.당신은 매우 몇 가지 가능한 키를 가지고 있다면, 난 그냥 열로 저장할 것입니다. 가능한 키 세트가 큰 경우 그러나 첫 번째 접근 방식은 좋은 (그리고 두 번째 방법은 불가능하다).

    당신은 매우 몇 가지 가능한 키를 가지고 있다면, 난 그냥 열로 저장할 것입니다. 가능한 키 세트가 큰 경우 그러나 첫 번째 접근 방식은 좋은 (그리고 두 번째 방법은 불가능하다).

    아니면 각 항목은 키의 유한 수를 가질 수 있지만, 키가 큰 세트에서 뭔가 할 수 있도록인가?

    당신은 또한 쉽게 조회 할 객체 관계형 매퍼를 사용하여 고려할 수 있습니다.

  11. ==============================

    11.첫 번째 방법은 당신이 언급 비용으로 훨씬 더 유연합니다.

    첫 번째 방법은 당신이 언급 비용으로 훨씬 더 유연합니다.

    그리고 두 번째 방법은 가리 켰을 때, 결코 실용적이다. 대신 당신이 할 것 (첫 번째 예에 따라)

    create table item_config (item_id int, colour varchar, size varchar, fabric varchar)
    

    의 물론 이것은 단지 데이터의 양이 알려져 있고 많이 변경하지 않을 때 작동합니다.

    일반적으로 정상적인 작업을 할 테이블의 DDL을 변화하는 요구하는 응용 프로그램은 두 번째와 세 번째의 생각을 부여해야합니다.

  12. ==============================

    12.정규화 규칙을 위반하면 한 비즈니스 요구 사항이 여전히 충족 될 수 괜찮습니다. key_1, 개, key_2 1, 값을 갖는, ... key_n, value_n이 바로 점까지 당신은 + 1 key_n 필요가 없다는 것을 확인 할 수있다, value_n + 1.

    정규화 규칙을 위반하면 한 비즈니스 요구 사항이 여전히 충족 될 수 괜찮습니다. key_1, 개, key_2 1, 값을 갖는, ... key_n, value_n이 바로 점까지 당신은 + 1 key_n 필요가 없다는 것을 확인 할 수있다, value_n + 1.

    내 솔루션은 고유 속성 공유 속성과 XML 데이터의 테이블이었다. 그 말은 내가 모두를 사용합니다. 모든 (또는 대부분의 일들이) 크기있는 경우에, 크기는 테이블의 열입니다. 단지 객체 A는 속성 Z이 경우 Z는 XML 이미 주어진 피터 마샬의 대답 유사한로 저장됩니다.

  13. ==============================

    13.두 번째 테이블이 심하게 디 정규화된다. 나는 첫 번째 방법을 고수한다.

    두 번째 테이블이 심하게 디 정규화된다. 나는 첫 번째 방법을 고수한다.

  14. ==============================

    14.나는 자주 항목 변화의 지정된 형태의 키 / 값만큼, 옳은 일을하고 있다고 생각. 그들은 오히려 정적 인 경우에, 단순히 넓은 아이템 테이블이 더 의미하고.

    나는 자주 항목 변화의 지정된 형태의 키 / 값만큼, 옳은 일을하고 있다고 생각. 그들은 오히려 정적 인 경우에, 단순히 넓은 아이템 테이블이 더 의미하고.

    우리는 값의 유형에 대한 키 / 값 주위 논리의 많은뿐만 아니라, 테이블, 각 키에 허용 비슷한 (하지만 오히려 더 복잡한) 방법을 사용합니다. 이것은 우리가 키의 또 다른 인스턴스로 항목을 정의 할 수 있습니다, 우리의 중앙 테이블은 다른 임의의 키 유형에 임의의 키 유형을 매핑합니다. 그것은 신속하게 노트에 당신의 두뇌를 묶을 수있다, 그러나 당신이 작성하고 모든 그것을 처리하는 로직을 캡슐화 한 후, 당신은 많은 유연성을 가지고있다.

    나는 필요한 경우 우리가하는 일의 자세한 내용을 작성할 수 있습니다.

  15. ==============================

    15.키가 동적 또는 이들의 부하가있는 경우, 당신은 첫 번째 예로서 가지고 있다는 매핑 테이블을 사용합니다. 당신이 더 많은 키를 추가로 또한 이것은이 (가 데이터를 얻을 수있는 SQL 코드에 쉽게, 그리고 데이터베이스가 당신이 상상하는 것보다 더 나은 쿼리를 최적화 할 수있을 것입니다 미래에 가장 가장 일반적인 솔루션을 확장한다 즉, 나는 그것이 당신이 다음 두 가지 옵션 아래)을 고려할 수있는 경우 나중에 테스트에서 병목 현상, 입증되지 않는 한 조기에이 사건을 최적화에 노력을하지 않을 것입니다.

    키가 동적 또는 이들의 부하가있는 경우, 당신은 첫 번째 예로서 가지고 있다는 매핑 테이블을 사용합니다. 당신이 더 많은 키를 추가로 또한 이것은이 (가 데이터를 얻을 수있는 SQL 코드에 쉽게, 그리고 데이터베이스가 당신이 상상하는 것보다 더 나은 쿼리를 최적화 할 수있을 것입니다 미래에 가장 가장 일반적인 솔루션을 확장한다 즉, 나는 그것이 당신이 다음 두 가지 옵션 아래)을 고려할 수있는 경우 나중에 테스트에서 병목 현상, 입증되지 않는 한 조기에이 사건을 최적화에 노력을하지 않을 것입니다.

    키가 알려진 설정, 그리고, 거기에 그들 중 많은 수없는 경우 (<10, 어쩌면 <5), 그때는 항목에 값 열로있는에서 문제를 볼 수 없습니다.

    알려진 고정 키 (10-30)의 중간 번호가있는 경우 다음 어쩌면 item_details을 유지하는 또 다른 테이블이 있습니다.

    내가 두 번째 예 구조를 사용할 필요가 표시되지 않습니다하지만 성가신 보인다.

  16. ==============================

    16.당신이 KVP 테이블의 경로를 이동하고, 쿼리에 참으로 어렵 기 때문에 나는 전혀 그 기술을 좋아하지 않아 자신을 말해야하는 경우에, 당신은 함께 적절한 기술을 사용하여 단일 항목 ID의 값을 클러스터링 고려해야한다 어떤 플랫폼에 당신은에있어.

    당신이 KVP 테이블의 경로를 이동하고, 쿼리에 참으로 어렵 기 때문에 나는 전혀 그 기술을 좋아하지 않아 자신을 말해야하는 경우에, 당신은 함께 적절한 기술을 사용하여 단일 항목 ID의 값을 클러스터링 고려해야한다 어떤 플랫폼에 당신은에있어.

    RDBMS의 인서트에 피하기 블록 경합에 주위 분산 행하는 경향이 있고 8 rowes이 있다면 당신은 쉽게 자신을 읽을 수있는 테이블의 8 블록에 접근 찾을 수있는 검색합니다. 오라클에서 당신은 크게 주어진 항목 ID 값을 액세스하는 방법에 대한 성능을 향상시킬 것이를 저장하는 해시 클러스터를 고려할 잘 할 것입니다.

  17. ==============================

    17.귀하의 예는 키 값 쌍의 사용으로 아주 좋은 예가 아니다. 더 좋은 예는 청구 응용 프로그램에서 요금 테이블 고객 테이블과 Customer_Fee 테이블 같은 것을 사용 될 것이다. 요금 테이블과 같은 필드로 구성 것이다 :     fee_id, FEE_NAME, fee_description Customer_Fee 테이블과 같은 필드로 구성 것이다 :     CUSTOMER_ID, fee_id, fee_value

    귀하의 예는 키 값 쌍의 사용으로 아주 좋은 예가 아니다. 더 좋은 예는 청구 응용 프로그램에서 요금 테이블 고객 테이블과 Customer_Fee 테이블 같은 것을 사용 될 것이다. 요금 테이블과 같은 필드로 구성 것이다 :     fee_id, FEE_NAME, fee_description Customer_Fee 테이블과 같은 필드로 구성 것이다 :     CUSTOMER_ID, fee_id, fee_value

  18. ==============================

    18.시간이 변경되었습니다. 지금 당신은 당신이 관계형 데이터베이스 옆에 사용할 수있는 다른 데이터베이스 유형이있다. (: http://en.wikipedia.org/wiki/NoSQL 참조) NOSQL 선택은 지금, 열 저장, 문서 저장, 그래프, 및 다중 모델을 포함한다.

    시간이 변경되었습니다. 지금 당신은 당신이 관계형 데이터베이스 옆에 사용할 수있는 다른 데이터베이스 유형이있다. (: http://en.wikipedia.org/wiki/NoSQL 참조) NOSQL 선택은 지금, 열 저장, 문서 저장, 그래프, 및 다중 모델을 포함한다.

    키 - 값 데이터베이스의 경우, 당신의 선택은 다음을 포함 (이에 국한되지 않음) CouchDB를, 레디 스 및 MongoDB를.

  19. from https://stackoverflow.com/questions/126271/key-value-pairs-in-relational-database by cc-by-sa and MIT license