[mysql] MySQL에 JSON으로 데이터 저장

나는 이것이 n00b 일이라고 생각했습니다. 그래서 저는 한 번도 해본 적이 없습니다. 그런 다음 FriendFeed가이 작업을 수행하고 실제로 DB 확장을 개선하고 지연 시간을 줄이는 것을 확인했습니다. 이걸해야하는지 궁금합니다. 그렇다면 올바른 방법은 무엇입니까?

기본적으로 MySQL의 모든 것을 CouchDB 일종의 DB로 저장하는 방법을 배우기에 좋은 곳은 어디입니까? 모든 것을 JSON으로 저장하는 것이 더 쉽고 빠릅니다 (빌드하는 것이 아니라 지연 시간이 적음).

또한 DB에 JSON으로 저장되어있는 내용을 편집, 삭제 등이 쉬운가요?



답변

CouchDB와 MySQL은 매우 다른 두 가지입니다. JSON은 CouchDB에 물건을 저장하는 기본 방법입니다. MySQL에서 가장 좋은 방법은 JSON 데이터를 단일 필드에 텍스트로 저장하는 것입니다. 이것은 RDBMS에 저장하는 목적을 완전히 무너 뜨리고 모든 데이터베이스 트랜잭션을 매우 복잡하게 만듭니다.

하지마.

그래도 FriendFeed 는 MySQL 위에 극도로 사용자 정의 된 스키마 를 사용하는 것 같았습니다 . 정확히 무엇을 저장하고 싶은지에 따라 달라지며, 데이터베이스 시스템을 남용하는 방법에 대한 명확한 답은 거의 없으므로 이해가됩니다. 이 기사가 매우 오래되었고 Mongo와 Couch에 대한 주된 이유가 미성숙이라는 점을 감안할 때 MySQL이 당신을 위해 그것을 자르지 않으면이 두 가지를 다시 평가할 것입니다. 그들은 지금까지 많이 성장 했어야했다.


답변

모든 댓글이 잘못된 각도에서 오는 것 같습니다. PHP를 통해 관계형 DB에 JSON 코드를 저장하는 것이 좋으며 실제로 이와 같은 복잡한 데이터를로드하고 표시하는 것이 더 빠르지 만 다음과 같은 설계 고려 사항이 있습니다. 검색, 인덱싱 등

이를 수행하는 가장 좋은 방법은 하이브리드 데이터를 사용하는 것입니다. 예를 들어 날짜 시간을 기준으로 검색해야하는 경우 MySQL (성능 조정 됨)이 PHP보다 훨씬 빠르며 장소 검색 거리와 같은 경우 MySQL도 많이 사용해야합니다. 더 빠릅니다 (검색에 액세스하지 않음). 검색 할 필요가없는 데이터는 JSON, BLOB 또는 실제로 필요하다고 생각하는 다른 형식으로 저장할 수 있습니다.

액세스해야하는 데이터는 기본 사례 별 송장 시스템과 같이 JSON으로 매우 쉽게 저장됩니다. 그것들은 RDBMS에서 그다지 이익을 얻지 못하며, 올바른 HTML 양식 구조가있는 경우 json_encoding ($ _ POST [ ‘entires’])만으로 JSON에 저장할 수 있습니다.

MongoDB를 사용하게되어 기쁘고 계속해서 좋은 서비스를 제공하기를 바라지 만, 앱의 복잡성이 증가하면 결국 RDBMS가 필요할 수 있으므로 MySQL이 항상 당신의 레이더에서 벗어날 것이라고 생각하지 마십시오. 일부 기능 및 기능 (아카이브 된 데이터 또는 비즈니스보고를 중단하는 경우에도 해당)


답변

MySQL 5.7은 이제 MongoDB 및 기타 스키마없는 문서 데이터 저장소와 유사한 기본 JSON 데이터 유형을 지원합니다.

JSON 지원

MySQL 5.7.8부터 MySQL은 네이티브 JSON 유형을 지원합니다. JSON 값은 문자열로 저장되지 않고 대신 문서 요소에 대한 빠른 읽기 액세스를 허용하는 내부 바이너리 형식을 사용합니다. JSON 열에 저장된 JSON 문서는 삽입 또는 업데이트 될 때마다 자동으로 유효성이 검사되며 잘못된 문서는 오류를 생성합니다. JSON 문서는 생성시 정규화되며 =, <, <=,>,> =, <>,! = 및 <=>와 같은 대부분의 비교 연산자를 사용하여 비교할 수 있습니다. 지원되는 연산자와 MySQL이 JSON 값을 비교할 때 따르는 우선 순위 및 기타 규칙에 대한 자세한 내용은 JSON 값 비교 및 ​​순서 지정을 참조하십시오.

MySQL 5.7.8은 또한 JSON 값 작업을위한 여러 함수를 도입했습니다. 이러한 기능에는 다음과 같은 기능이 포함됩니다.

  1. JSON 값을 생성하는 함수 : JSON_ARRAY (), JSON_MERGE () 및 JSON_OBJECT (). Section 12.16.2,“JSON 값을 생성하는 함수”를 참조하십시오.
  2. JSON 값을 검색하는 함수 : JSON_CONTAINS (), JSON_CONTAINS_PATH (), JSON_EXTRACT (), JSON_KEYS () 및 JSON_SEARCH (). Section 12.16.3,“JSON 값을 검색하는 함수”를 참조하십시오.
  3. JSON 값을 수정하는 함수 : JSON_APPEND (), JSON_ARRAY_APPEND (), JSON_ARRAY_INSERT (), JSON_INSERT (), JSON_QUOTE (), JSON_REMOVE (), JSON_REPLACE (), JSON_SET () 및 JSON_UNQUOTE (). Section 12.16.4,“JSON 값을 수정하는 함수”를 참조하십시오.
  4. JSON 값에 대한 정보를 제공하는 함수 : JSON_DEPTH (), JSON_LENGTH (), JSON_TYPE () 및 JSON_VALID (). Section 12.16.5,“JSON 값 속성을 반환하는 함수”를 참조하십시오.

MySQL 5.7.9 이상에서는 JSON_EXTRACT (열, 경로)의 약어로 column-> path를 사용할 수 있습니다. 이것은 WHERE, ORDER BY 및 GROUP BY 절을 포함하여 SQL 문에서 열 식별자가 발생할 수있는 모든 열에 대한 별칭으로 작동합니다. 여기에는 SELECT, UPDATE, DELETE, CREATE TABLE 및 기타 SQL 문이 포함됩니다. 왼쪽은 별칭이 아니라 JSON 열 식별자 여야합니다. 오른쪽은 열 값으로 반환 된 JSON 문서에 대해 평가되는 인용 된 JSON 경로 표현식입니다.

-> 및 JSON_EXTRACT ()에 대한 자세한 내용은 Section 12.16.3,“JSON 값을 검색하는 함수”를 참조하십시오. MySQL 5.7의 JSON 경로 지원에 대한 자세한 내용은 JSON 값 검색 및 수정을 참조하십시오. Secondary Indexes 및 Virtual Generated Columns도 참조하십시오.

더 많은 정보:

https://dev.mysql.com/doc/refman/5.7/en/json.html


답변

json 문자는 스토리지와 관련하여 특별한 것이 아닙니다.

{, }, [, ], ', a-z, 0-9…. 정말 특별한 아무것도 및 텍스트로 저장할 수 있습니다.

당신이 가질 첫 번째 문제는

{profile_id : 22, 사용자 이름 : ‘Robert’, 비밀번호 : ‘skhgeeht893htgn34ythg9er’}

자신의 절차가 있고 mysql 용 jsondecode를 개발하지 않는 한 데이터베이스에 저장된 것은 업데이트하기가 쉽지 않습니다.

UPDATE users SET JSON(user_data,'username') = 'New User';

그래서 그렇게 할 수 없기 때문에 먼저 json을 선택하고, 디코딩하고, 변경하고, 업데이트해야하므로 이론적으로 적절한 데이터베이스 구조를 구성하는 데 더 많은 시간을 소비하는 것이 좋습니다!

저는 json을 사용하여 데이터를 저장하지만 메타 데이터 만 사용합니다. 사용자 특정과 관련이없고 자주 업데이트되지 않는 데이터입니다. 예를 들어 사용자가 게시물을 추가하고 해당 게시물에 이미지를 추가하면 이미지를 파싱하고 엄지 손가락을 만들고 그런 다음 json 형식의 엄지 URL을 사용하십시오.


답변

쿼리를 사용하여 JSON 데이터를 얻는 것이 얼마나 어려운지 설명하기 위해이를 처리하기 위해 만든 쿼리를 공유하겠습니다.

배열이나 다른 객체는 고려하지 않고 기본 데이터 유형 만 고려합니다. 4 개의 column 인스턴스를 JSON을 저장하는 열 이름으로 변경하고 myfield 의 4 개 인스턴스 를 액세스하려는 JSON 필드로 변경 해야합니다.

SELECT
    SUBSTRING(
        REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
        LOCATE(
            CONCAT('myfield', ':'),
            REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
        ) + CHAR_LENGTH(CONCAT('myfield', ':')),
        LOCATE(
            ',',
            SUBSTRING(
                REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', ''),
                LOCATE(
                    CONCAT('myfield', ':'),
                    REPLACE(REPLACE(REPLACE(column, '{', ''), '}', ','), '"', '')
                ) + CHAR_LENGTH(CONCAT('myfield', ':'))
            )
        ) - 1
    )
    AS myfield
FROM mytable WHERE id = '3435'


답변

실제로 사용 사례에 따라 다릅니다. 보고에 전혀 가치가없고 다른 테이블과의 JOIN을 통해 쿼리되지 않는 정보를 저장하는 경우 JSON으로 인코딩 된 단일 텍스트 필드에 데이터를 저장하는 것이 합리적 일 수 있습니다.

이는 데이터 모델을 크게 단순화 할 수 있습니다. 그러나 RobertPitt가 언급했듯이이 데이터를 정규화 된 다른 데이터와 결합 할 수있을 것이라고 기대하지 마십시오.


답변

이것은 오래된 질문이지만 구글 검색 결과 상단에서 여전히 볼 수 있기 때문에 질문을 받고 4 년 후에 새로운 답변을 추가하는 것이 의미가있을 것 같다.

우선 RDBMS에 JSON을 저장하는 데 더 나은 지원이 있습니다. PostgreSQL로 전환하는 것을 고려할 수 있습니다 (MySQL은 v5.7.7부터 JSON을 지원했지만). PostgreSQL은 더 많은 기능을 지원한다는 점을 제외하고는 MySQL과 매우 유사한 SQL 명령을 사용합니다. 그들이 추가 한 함수 중 하나는 JSON 데이터 유형을 제공하고 이제 저장된 JSON을 쿼리 할 수 ​​있다는 것입니다. (이에 대한 일부 참조 ) 예를 들어 php에서 PDO를 사용하거나 Laravel에서 eloquent를 사용하여 프로그램에서 직접 쿼리를 작성하지 않는 경우 서버에 PostgreSQL을 설치하고 데이터베이스 연결 설정을 변경하기 만하면됩니다. 코드를 변경할 필요도 없습니다.

대부분의 경우 다른 답변에서 제안했듯이 RDBMS에서 직접 JSON으로 데이터를 저장하는 것은 좋은 생각이 아닙니다. 하지만 몇 가지 예외가 있습니다. 내가 생각할 수있는 한 가지 상황은 가변 개수의 연결된 항목이있는 필드입니다.

예를 들어, 블로그 게시물의 태그를 저장하려면 일반적으로 블로그 게시물 용 테이블, 태그 테이블 및 일치하는 테이블이 필요합니다. 따라서 사용자가 게시물을 편집하고 해당 게시물과 관련된 태그를 표시해야하는 경우 3 개의 테이블을 쿼리해야합니다. 매칭 테이블 / 태그 테이블이 길면 성능이 크게 저하됩니다.

태그를 블로그 게시물 테이블에 JSON으로 저장하면 동일한 작업에 단일 테이블 검색 만 필요합니다. 그러면 사용자는 블로그 게시물을 더 빨리 볼 수 있지만 태그에 연결된 게시물에 대한 보고서를 작성하거나 태그로 검색하려는 경우 성능이 저하됩니다.

데이터베이스의 비정규 화를 시도 할 수도 있습니다. 데이터를 복제하고 두 가지 방법으로 데이터를 저장하면 두 가지 방법의 이점을 모두 얻을 수 있습니다. 데이터를 저장하는 데 약간의 시간과 더 많은 저장 공간이 필요합니다 (더 많은 컴퓨팅 성능에 비해 저렴함).