JSON을 데이터베이스에 저장하는 것과 각 키에 대해 새로운 열이 있는 경우
하기 위해 . 두 개의. 2번입니다.uid
키)및a ('프라이머리 키')meta
컬럼에는 사용자에 대한 기타 데이터가 JSON 형식으로 저장됩니다.
uid | meta
--------------------------------------------------
1 | {name:['foo'],
| emailid:['foo@bar.com','bar@foo.com']}
--------------------------------------------------
2 | {name:['sann'],
| emailid:['sann@bar.com','sann@foo.com']}
--------------------------------------------------
에는 ''와 같은 열이 있는 '' ,면) 더요?uid
,name
,emailid
첫 번째 모델의 마음에 드는 점은 가능한 한 많은 필드를 추가할 수 있다는 것입니다.
또, 첫 번째 모델을 실장하고 나서, 궁금했습니다.foo와 같은 이름을 가진 모든 사용자를 가져오려면 어떻게 해야 합니까?
질문 - JSON과 필드당 컬럼 중 어느 쪽을 사용하여 사용자 관련 데이터를 데이터베이스에 저장하는 것이 더 좋습니까(필드 수는 고정되어 있지 않다는 점에 유의하십시오).또한 첫 번째 모델이 구현될 경우 위와 같이 데이터베이스를 조회하는 방법은 무엇입니까?쿼리로 검색할 수 있는 모든 데이터와 다른 데이터를 JSON(다른 행)에 저장하여 두 모델을 모두 사용해야 합니까?
갱신하다
검색해야 할 열이 많지 않기 때문에 두 모델을 모두 사용하는 것이 현명할까요?검색해야 하는 데이터의 경우 열당 키, 기타 데이터의 경우 JSON(동일한 MySQL 데이터베이스 내)
2017년 6월 4일 갱신
이 질문/답변은 인기를 얻고 있기 때문에 갱신할 가치가 있다고 생각했습니다.
이 질문이 처음 게시되었을 때 MySQL은 JSON 데이터 유형 및 Postgre 지원을 지원하지 않았습니다.SQL은 초기 단계였습니다.5.7 이후 MySQL은 JSON 데이터 유형(바이너리 스토리지 형식)과 Postgre를 지원하게 되었습니다.SQL JSONB는 상당히 성숙했습니다.두 제품 모두 JSON 개체의 특정 키 인덱싱 지원을 포함하여 임의 문서를 저장할 수 있는 성능 JSON 유형을 제공합니다.
그러나 관계형 데이터베이스를 사용할 때 기본 선호도는 여전히 값당 열이어야 한다는 원래 진술을 고수합니다.관계형 데이터베이스는 여전히 데이터 내의 데이터가 상당히 잘 정규화될 것이라는 가정 하에 구축됩니다.쿼리 플래너는 열을 볼 때 JSON 문서에서 키를 볼 때보다 더 나은 최적화 정보를 제공합니다.외부 키는 열 사이에 만들 수 있습니다(JSON 문서의 키 간에는 만들 수 없습니다).중요: 스키마의 대부분이 JSON을 사용하는 것이 정당화될 정도로 휘발성이 높은 경우, 적어도 관계형 데이터베이스가 올바른 선택인지 검토할 수 있습니다.
즉, 완전한 관계형 애플리케이션이나 문서 지향 애플리케이션은 거의 없습니다.대부분의 어플리케이션에는 양쪽이 혼재되어 있습니다.다음은 개인적으로 관계형 데이터베이스에서 JSON이 유용하다는 것을 알게 된 몇 가지 예입니다.
연락처의 이메일 주소와 전화번호를 저장하는 경우 여러 개의 개별 테이블보다 JSON 배열에 값으로 저장하는 것이 훨씬 쉽습니다.
임의의 키/값 사용자 기본 설정 저장(값이 부울, 텍스트 또는 숫자일 수 있으며 다른 데이터 유형에 대해 별도의 열을 원하지 않음)
정의된 스키마가 없는 구성 데이터 저장(Zapier 또는 IFTT를 구축하여 각 통합에 대한 구성 데이터를 저장해야 하는 경우)
물론 다른 사람들도 있겠지만, 이것들은 몇 가지 간단한 예에 불과합니다.
원답
임의의 문서 크기 제한 없이 원하는 수만큼 필드를 추가할 수 있도록 하려면 MongoDB와 같은 NoSQL 솔루션을 고려하십시오.
관계형 데이터베이스의 경우: 값당 하나의 열을 사용합니다.JSON BLOB을 열에 넣으면 사실상 쿼리를 수행할 수 없게 됩니다(실제로 동작하는 쿼리를 발견하면 매우 느려집니다).
관계형 데이터베이스는 인덱싱할 때 데이터 유형을 활용하며 정규화된 구조로 구현되도록 설계되었습니다.
참고로 JSON을 관계형 데이터베이스에 저장해서는 안 됩니다.실제 메타데이터를 추가하거나 JSON이 쿼리할 필요가 없고 표시용으로만 사용되는 정보를 기술하고 있는 경우 모든 데이터 포인트에 대해 별도의 열을 만드는 것은 오버킬일 수 있습니다.
다른 것들과 마찬가지로, "에 따라 달라"데이터를 열이나 JSON에 저장하는 것 자체가 옳거나 그르거나 좋거나 나쁘지는 않습니다.나중에 어떻게 하느냐에 따라 다르죠.이 데이터에 액세스하는 예상 방법은 무엇입니까?다른 데이터를 상호 참조해야 합니까?
다른 사람들은 기술적 트레이드오프가 무엇인지 꽤 잘 대답했습니다.
앱과 기능이 시간이 지남에 따라 진화하고 이 데이터 스토리지 결정이 팀에 어떤 영향을 미치는지에 대해 논의한 사람은 많지 않습니다.
JSON을 사용하는 이유 중 하나는 스키마의 이행을 회피하는 것이기 때문에 팀이 훈련을 받지 않으면 JSON 필드에 다른 키/값 쌍을 추가하는 것이 매우 쉽습니다.이주를 위한 것도 없고, 그 용도를 기억하는 사람도 없습니다.그것은 검증되지 않았다.
우리 팀은 포스트그레의 전통적인 기둥을 따라 JSON을 사용했는데, 처음에는 빵 슬라이스 이후 최고의 것이었습니다.JSON은 매력적이고 강력한 기업이었지만, 어느 날 유연성이라는 것은 비용이 많이 든다는 것을 깨달았습니다.그것은 갑자기 큰 과제입니다.때로는 이 점이 매우 빠르게 떠오르기도 하고, 그 후에는 변경하기가 어려워지기도 합니다. 왜냐하면 이 설계 결정 위에 다른 많은 것들을 구축했기 때문입니다.
초과 근무, 새로운 기능 추가, JSON에 데이터 저장으로 인해 기존 열을 사용할 경우 추가될 수 있는 쿼리보다 더 복잡해 보이는 쿼리가 발생했습니다.그래서 우리는 어떤 중요한 값들을 다시 열로 끌어내기 시작했습니다. 그래서 우리는 결합을 하고 값들을 비교할 수 있었습니다.안 좋은 생각이야.이제 우리는 복제가 있었다.새로운 개발자가 합류하면 혼란스러울까요?어떤 가치를 다시 저장해야 할까요?JSON 하나? 아니면 열?
JSON 필드는 이것저것 작은 것들로 인해 쓰레기 서랍이 되었다.데이터베이스 수준에서 데이터 검증이 수행되지 않으며 문서 간의 일관성 또는 무결성이 없습니다.그 결과 기존의 컬럼에서 하드타입과 제약체크를 받는 대신 앱에 모든 책임을 떠넘겼습니다.
돌이켜보면, JSON은 우리가 매우 빠르게 반복하고 무언가를 문 밖으로 꺼낼 수 있게 해주었다.아주 훌륭했어요.그러나 일정 규모의 팀에 도달한 후에는 유연성이라는 점에서 기술적인 부담에 시달릴 수밖에 없었습니다.그 결과, 기능의 진화가 늦춰졌습니다.주의하여 사용하십시오.
데이터의 성질이 무엇인지에 대해 오랫동안 잘 생각해 보십시오.앱의 기반입니다.시간이 지남에 따라 데이터가 어떻게 사용될 것인가?그리고 어떻게 변할 것 같습니까?
WordPress는 이런 종류의 것을 위한 구조를 가지고 있습니다(적어도 WordPress는 제가 처음 관찰한 곳이고 아마 다른 곳에서 유래했을 것입니다).
무제한 키를 사용할 수 있으며 JSON Blob을 사용하는 것보다 검색 속도가 빠르지만 일부 NoSQL 솔루션만큼 빠르지는 않습니다.
uid | meta_key | meta_val
----------------------------------
1 name Frank
1 age 12
2 name Jeremiah
3 fav_food pizza
.................
편집
이력/복수 키 저장용
uid | meta_id | meta_key | meta_val
----------------------------------------------------
1 1 name Frank
1 2 name John
1 3 age 12
2 4 name Jeremiah
3 5 fav_food pizza
.................
다음과 같은 방법으로 질문합니다.
select meta_val from `table` where meta_key = 'name' and uid = 1 order by meta_id desc
접근법의 단점은 바로 당신이 말한 것입니다.
텍스트 검색을 수행할 때마다 검색 속도가 매우 느립니다.
대신 문자열 전체와 일치합니다.
검색 기준이 필요 없고 일반 데이터와 함께 표시만 하면 되는 접근 방식(JSON 기반 데이터)이 적합합니다.
편집: 명확히 하기 위해 위의 내용은 기존의 관계형 데이터베이스에 적용됩니다.NoSQL은 내부적으로 JSON을 사용하며, 이것이 바람직한 동작이라면 아마도 더 나은 옵션일 것입니다.
기본적으로 사용하는 첫 번째 모델은 문서 기반 스토리지라고 합니다.MongoDB나 CouchDB와 같은 일반적인 NoSQL 문서 기반 데이터베이스를 살펴봐야 합니다.기본적으로 문서 기반 DB에서는 데이터를 json 파일에 저장한 후 이러한 json 파일에 대해 쿼리할 수 있습니다.
두 번째 모델은 널리 사용되는 관계형 데이터베이스 구조입니다.
MySql과 같은 관계형 데이터베이스를 사용하고 싶다면 두 번째 모델만 사용하는 것이 좋습니다.첫 번째 모델처럼 MySql을 사용하고 데이터를 저장하는 것은 의미가 없습니다.
두 번째 질문에 답하려면 첫 번째 모델을 사용하는 경우 'foo'와 같은 이름을 조회할 방법이 없습니다.
주로 관계형 모델을 사용할지 망설이는 것 같습니다.
현재 상태로는 관계형 모델에 적합하지만 이 모델을 진화시켜야 할 때 문제가 발생할 수 있습니다.
메인 엔티티(사용자)의 어트리뷰트 레벨이 1개(또는 몇 개)밖에 없는 경우에도 관계형 데이터베이스에서 Entity Attribute Value(EAV; 엔티티 속성값) 모델을 사용할 수 있습니다.(이것에도 장단점이 있습니다.)
응용 프로그램을 사용하여 검색하려는 값이 구조화되지 않을 것으로 예상되면 MySQL을 선택하는 것이 가장 좋지 않을 수 있습니다.
Postgre를 사용하는 경우SQL은 두 가지 장점을 모두 활용할 수 있습니다. (이는 실제 데이터 구조에 따라 달라집니다.)MySQL도 반드시 잘못된 선택은 아니며, NoSQL 옵션도 관심이 있을 수 있습니다.대안을 제안하고 있을 뿐입니다.)
정말이야, 포스트그레SQL은 (MySQL은 알 수 없는) 함수를 기반으로 인덱스를 작성할 수 있으며, 최근 버전에서는 JSON 데이터에 PLV8을 직접 사용하여 관심 있는 특정 JSON 요소에 인덱스를 구축할 수 있으므로 데이터를 검색할 때 쿼리 속도가 향상됩니다.
편집:
검색해야 할 열이 많지 않기 때문에 두 모델을 모두 사용하는 것이 현명할까요?검색해야 하는 데이터의 경우 열당 키, 기타 데이터의 경우 JSON(동일한 MySQL 데이터베이스 내)
두 모델을 혼합하는 것이 반드시 잘못된 것은 아니지만(추가 공간이 무시할 수 있다고 가정하면), 두 데이터 세트를 동기화 상태로 유지하지 않으면 문제가 발생할 수 있습니다. 응용 프로그램은 다른 모델을 업데이트하지 않고 한 모델을 변경하지 않아야 합니다.
이를 위해서는 업데이트 또는 삽입이 이루어질 때마다 데이터베이스 서버 내에서 저장 프로시저를 실행하여 트리거가 자동 업데이트를 수행하도록 하는 것이 좋습니다.제가 알기로는 MySQL 스토어드 프로시저 언어는 어떤 종류의 JSON 처리도 지원하지 않는 것 같습니다.어게인 포스트그레PLV8을 지원하는 SQL(및 보다 유연한 스토어드 프로시저 언어를 사용하는 기타 RDBMS)이 더 유용해야 합니다(트리거를 사용하여 관계 열을 자동으로 업데이트하는 것은 인덱스를 업데이트하는 것과 거의 유사합니다).
테이블에서 조인하는 시간이 오버헤드가 됩니다.OLAP의 경우 테이블이 두 개일 경우 하나는 ORDER 테이블이고 다른 하나는 ORDER_DETAILS입니다.2개의 테이블을 결합할 필요가 있는 모든 주문 세부 정보를 얻기 위해 테이블 내의 행이 증가하지 않으면 쿼리가 느려집니다(예를 들어 수백만 단위).왼쪽/오른쪽 조인 속도가 내부 조인보다 너무 느립니다.각각의 ORDER 엔트리에 JSON string/Object를 추가하면 JOIN은 피할 수 있을 것 같습니다.보고서 추가 생성 속도가 빨라집니다...
단답은 그들 사이에 섞어야 합니다.연락처 데이터, 주소, 제품 종류와 같이 그들과 관계를 맺지 않을 데이터에 json을 사용합니다.
비관계형 모델을 관계형 데이터베이스에 맞추려고 하는데, MongoDB와 같은 NoSQL 데이터베이스를 사용하는 것이 좋을 것 같습니다.필드 수에 제한이 없는 요건에 적합한 사전 정의된 스키마는 없습니다(일반적인 MongoDB 수집 예 참조).MongoDB 문서를 참조하여 문서를 조회하는 방법에 대한 아이디어를 얻으려면 다음과 같이 하십시오.
db.mycollection.find(
{
name: 'sann'
}
)
다른 사람들이 지적했듯이 쿼리는 더 느릴 것이다.적어도 '_'를 추가하는 것이 좋습니다.ID' 열을 대신 쿼리합니다.
언급URL : https://stackoverflow.com/questions/15367696/storing-json-in-database-vs-having-a-new-column-for-each-key
'source' 카테고리의 다른 글
MySql 오류:저장된 함수/트리거를 호출한 문에서 이미 사용되고 있으므로 저장된 함수/트리거의 테이블을 업데이트할 수 없습니다. (0) | 2022.11.26 |
---|---|
LocalDate를 Instant로 변환하는 방법 (0) | 2022.11.26 |
JavaScript에는 지정된 범위 내에서 범위를 생성하는 "range()"와 같은 메서드가 있습니까? (0) | 2022.11.26 |
웹 페이지를 통해 파라미터를 PHP 스크립트로 전달하려면 어떻게 해야 합니까? (0) | 2022.11.26 |
시제품의 목적은 무엇입니까? (0) | 2022.11.26 |