15

레거시 POI 데이터베이스를 MySQL에서 PostgreSQL으로 재 설계해야합니다. 현재 모든 엔티티에는 개별 속성을 나타내는 80-120 + 속성이 있습니다.은 EAV - Hybrid입니다. 잘못된 데이터베이스 디자인 선택

우리는 새로운 데이터베이스에 대한 유연성과 디자인 방식을 고려해야합니다. 그러나 새로운 디자인은 허용해야한다 :

  • N 아니오. 어떤 엔티티에 대한 속성/속성의 예 : 어떤 엔티티에 대한 속성도 고정되어 있지 않으며 정기적으로 바뀔 수 있습니다.

  • 콘텐츠 관리자는 항상 db 스키마를 변경하는 대신 admin 인터페이스를 통해 에 새로운 속성을 추가 할 수 있습니다 ().

는 EAV의 성능 문제에 대한 꽤 많은 논의가 있지만 우리는 하이브리드 EAV와 함께 가지 않으면 우리는 결국 : 빈 열

  • 가진 많은 (우리는 아직도 가서 데이터의 99 %에 해당 속성이없는 경우에도 새 열 추가)
  • 데이터베이스 유지 관리에 더 많은 시간이 소요됩니다. 속성이 계속 변경 될 때
  • 기존 개체 어쨌든 여기

을 새로운 속성을 추가 할 콘텐츠 관리자를 허용하는 방법은 (기본 ERD 포함) 우리가 새로운 디자인에 대해 생각입니다 :

  • 각각에 대해 별도의 테이블을 가지고 독점적 인 몇 가지 기본 정보를 포함하는 엔티티 ID, 이름, 주소, 연락처, 생성 된 항목 등

  • 속성 정보를 저장하기위한 2 개의 테이블 속성 유형 및 속성이 있습니다.

  • 다 대다 관계를 사용하여 각 엔터티를 특성에 연결하십시오.

  • 다른 테이블에 주소를 저장하고 외래 키를 사용하여 엔티티에 연결하십시오.

    alt text

우리는이 추가, 제거 또는 속성을 업데이트 할 때 더 유연하게 우리를있게 생각합니다.

그러나이 설계는 주어진 경기장에 대한 모든 "속성"을 표시하기 위해 데이터를 가져올 때 조인 횟수를 증가시킬 수 있습니다. 우리는 20 개 이상의 조인을 가진 쿼리를 사용하여 단일 행의 모든 ​​관련 속성을 가져올 수 있습니다.

이 디자인에 대한 귀하의 의견과 개선을위한 귀하의 조언은 무엇입니까?

읽어 주셔서 감사합니다.

+0

NOSQL 데이터베이스를 사용하면 도움이 될까요? http://nosql-database.org/ –

+0

데이터베이스 테이블의 필드에 JSON 또는 XML로 데이터를 저장하는 데 NoSQL이 필요하지 않으며 PostgreSQL을 사용하면 특정 필드에 기능적 인덱스를 만들 수 있습니다. – MkV

+2

프로덕션 데이터베이스의 필드는 다음과 같습니다. shouldn 'on the fly'에 추가되면 데이터 혼란을 막기위한 변경 제어가 있어야합니다. 일부 초기 설계를 수행하여이를 피하십시오. 필드가 1-1이고 테이블 변경에 지장이 없다면 적절한 테이블을 추가하거나 기존 테이블에 필드를 추가하십시오. – MkV

답변

1

기본적으로 EAV는 데이터베이스 내에 데이터베이스를 구현하려고 시도하고 있으며 광기로 연결됩니다.데이터를 가져 오는 쿼리는 지나치게 복잡해지며 데이터에는 일정한 순서로 유지하기위한 안정적이고 구체적인 모델이 없습니다.

제한된 응용 프로그램을 위해 EAV 시스템을 작성했지만 일반적으로 일반적인 해결책으로는 좋지 않습니다.

+0

좋은 점. 수십 가지의 예/아니오 속성을 계속해서 변화시키는 데 도움이되는 조언은 무엇입니까? – nka

+0

데이터를 직렬화하고 앱에서 처리하십시오. –

+5

예를 들어 모든 속성을 "속성"필드에 BLOB로 저장하면 속성을 사용하여 쿼리를 필터링 할 수 있습니까? 이것은 어플리케이션에서 수행 되어야만하고, 우리가 많은 결과에 대해 이야기한다면 이것은 (불필요한) 메모리 소비를 높일 수 있습니다. 대답에 대한 – acme

6

EAV는 일부 시나리오에서 유용 할 수 있습니다. 그러나 그것은 "어두운면"과 조금 비슷합니다. 강력하고 유연하며 매우 유혹적입니다. 그러나 그것은 쉬운 탈출구의 일부입니다. 적절한 분석 및 설계를 수행하는 쉬운 방법.

나는 "엔티티"가 너무 일반적이기 때문에 약간 이상하다고 생각합니다. 주소와 연락처와 같은 엔티티에 무엇이 연결되어야하는지에 대한 아이디어가있는 것 같습니다. 모델에 "Books"가 있기로 결정하면 어떨까요? 그들은 또한 주소와 연락처를 가지고 있습니까? 나는 당신이 올바른 일반화를 찾고 모델의 EAV 부분을 최소값으로 유지하려고 노력해야한다고 생각합니다. 특성의 특정 하위 집합을 표시하거나 값의 존재 여부를 테스트하거나 값을 기반으로 동작을 결정할 때마다 실제로 열로 모델링해야합니다.

이 시스템을 설계 할 때 더 좋은 기회를 얻지 못할 것입니다. 요구 사항은 이전 버전 이후로 알려져 있으며, 작동하는 버전과 그렇지 않은 버전도 있습니다. (단지 Second System Effect에 희생되지 마십시오)

+1

주셔서 감사합니다. 그래서 더 나은 접근 방법은 무엇입니까? 100 개 이상의 예/아니요 플래그가 각 엔티티에 첨부되어 있다면, 각 엔티티에 구분 된 플래그를 여러 테이블에서 공유하는 방식으로 분류하여 그룹화 한 다음 별도로 저장해야합니다. 그러면 이러한 플래그 집합을 외래 키를 사용하여 다른 엔터티에 연결할 수 있습니까? – nka

+0

마지막 코멘트에 나는 당신이하려는 것을 보았습니다. "화장실을 가지고있다", "사탕을 팔다"등의 예/아니오 플래그 세트의 경우 속성/값 모델도 사용했을 것입니다. 기본적으로 추가 된 메타 데이터를 사용하여 관심 분야에 대한 멋진 태깅 시스템을 수행하고 있습니다. 나는 "실재물"이라는 이름에 속아 넘어졌다. – Ronnis

27

저는 10M + 엔티티, 500M + 값 및 수백 가지 속성이있는 중앙 EAV 모델을 갖춘 10 년 된 시스템을 유지 관리하고 있습니다. 내 경험에 따른 디자인 고려 사항 :

특정 특성에 적용되는 비즈니스 논리가있는 경우 해당 특성을 명시 적 열로 가질 가치가 있습니다. EAV 속성은 정말 포괄적 인 것이어야합니다. 응용 프로그램은 속성 A와 속성 B를 구별해서는 안됩니다. 코드에서 EAV 속성에 대한 리터럴 참조를 발견하면 명시적인 열이어야합니다.

상당한 양의 빈 열을 갖는 것이 큰 기술적 인 문제는 아닙니다. 그것은 하나 개의 테이블에 결국 다른 문제를 구분해서 좋은 코딩 및 문서 관행을 필요로 하는가 :

  • 은 규칙 및 데이터의 어느 부분을 읽고 수정하는 응용 프로그램의 일부 알려 규칙이 있습니다.
  • 보기를 사용하면 디버깅 도구를 사용하여 데이터베이스를 쉽게 찾을 수 있습니다.
  • 테스트 데이터 생성기를 만들고 유지 관리하여 현재 관심이없는 모델 부분에 대해 스키마를 준수하는 더미 데이터를 쉽게 만들 수 있습니다.
  • 엄격한 데이터베이스 버전 관리를 사용하십시오. 스키마 변경을 수행하는 유일한 방법은 변경 스크립트를 추적하고 적용하는 도구를 사용해야합니다. PostgreSQL에는 스키마 변경을 자동화하는 킬러 기능 중 하나 인 트랜잭션 DDL이 있습니다.

PostgreSQL은 스키니 테이블을 정말로 좋아하지 않습니다. 각 속성 값은 모든 행을 통과하여 데이터를 함께 가져 오는 추가 작업 외에도 32 바이트의 데이터 저장 오버 헤드를 발생시킵니다. 대부분 속성을 일괄 처리로 읽고 쓰는 경우 어떤 식 으로든 행에 데이터를 직렬화하는 것을 고려하십시오. attr_ids int[], attr_values text[]은 하나의 옵션입니다. hstore는 다른 것으로, 또는 클라이언트 쪽 (json 또는 protobuf)과 같은 것입니다. 데이터베이스 측에서 특별한 것을 만질 필요가 없다면 말입니다.

모든 것을 하나의 단일 엔티티 테이블에 집어 넣지 마십시오. 그들이 합당한 방법으로 어떤 속성을 공유하지 않으면, 당신이 사용하는 특정 EAV 패턴의 여러 인스턴스를 사용하십시오. 그러나 동일한 패턴을 사용하고 다른 구성표간에 접근 코드를 공유하려고 시도하십시오. 엔티티 이름의 코드를 항상 매개 변수화 할 수 있습니다.

코드는 데이터이고 데이터는 코드라는 점을 항상 명심하십시오. 의사 결정을 메타 모델로 푸는 것과 코드로 표현하는 것 사이에 올바른 균형을 찾아야합니다. 메타 모델을 너무 많이 만들면 시스템을 수정하고 버전 관리 도구, 품질 보증 절차, 코드로 스테이징하는 것과 같은 종류의 능력이 필요하지만 도구가 없습니다. 본질적으로 당신은 매우 어색한 비표준 언어로 프로그래밍을 할 것입니다. 다른 한편으로, 만약 당신이 코드에 너무 많이 남겨두면 모든 사소한 변화는 당신의 소프트웨어의 새로운 버전을 필요로 할 것입니다. 사람들은 메타 모델을 너무 복잡하게 만드는 측면에서 실수하는 경향이 있습니다. 메타 모델을위한 개발자 도구를 개발하는 것은 어렵고 지루한 작업이며 제한적인 이점이 있습니다. 반면 커밋에서 배포까지 발생하는 모든 작업을 자동화하여 릴리스 프로세스를보다 저렴하게 만드는 것은 여러 가지 측면에서 이점이 있습니다.

+0

답장을 보내 주셔서 감사합니다. 각 엔티티에 고유 한 테이블과 속성이 있지만 일반적으로 사용되는 속성 만 "속성"테이블에 유지되는 하이브리드 eav 모델을 사용하려고합니다. 태그로 생각하면됩니다. 주어진 개체에 여러 개의 태그를 만들거나 첨부하십시오. – nka

+0

특정 논리에 대해 열을 사용하는 대신 두 가지 종류의 특성, 간단하고 어려운 특성을 만드는 방법은 무엇입니까? 하드 속성은 비즈니스 로직을 코드에 포함 할 수 있습니까? – djmj

3

전자 상거래 용으로 magento를 사용하면 EAV를 효과적으로 구현할 수 있습니다. 그 당시에는 EAV에 대해 많은 논란이있었습니다 만, 무한한 제품 속성을 다루기 위해 EAV보다 다른 솔루션을 제안 할 사람이 있습니다.

물론 세계의 모든 제품에 필요한 모든 열을 열거 할 수는 있지만 시간이 많이 걸리고 필연적으로 제품 속성을 잊어 버릴 수 있습니다.

결론은 다음과 같습니다. 무한한 물건에는 EAV를 사용하지만 모든 데이터베이스의 테이블에는 EAV를 사용하지 마십시오. 따라서 하이브리드 EAV 및 관계형 데이터베이스는 올바르게 완료되면 고정 된 열만 사용하여 수행 할 수없는 강력한 도구입니다.

+0

postgresql의 JSON이 대안입니다. –