source

MySQL에 JSON으로 데이터 저장

manycodes 2023. 1. 29. 20:18
반응형

MySQL에 JSON으로 데이터 저장

이건 말도 안 되는 일인 줄 알았는데그래서 한 번도 안 해봤어요그 후 FriendFeed가 이를 통해 실제로 DB 확장을 개선하고 대기 시간을 단축하는 것을 볼 수 있었습니다.이거 해야 되나?그렇다면 올바른 방법은 무엇일까요?

기본적으로 MySQL의 모든 것을 CouchDB와 같은 DB로 저장하는 방법을 배우기에 좋은 장소는 어디입니까?모든 것을 JSON으로 저장하면 더 쉽고 빠르게 구축할 수 있을 것 같습니다(구축하지 않고 지연 시간을 줄일 수 있습니다.

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

모든 코멘트가 잘못된 각도에서 오고 있는 것 같습니다.PHP를 통해 JSON 코드를 관계형 DB에 저장하는 것도 괜찮고, 실제로 이와 같은 복잡한 데이터를 로드하고 표시하는 것도 빠를 것입니다만, 검색이나 인덱싱등의 설계상의 고려사항이 있습니다.

이를 위한 가장 좋은 방법은 하이브리드 데이터를 사용하는 것입니다. 예를 들어 datetime MySQL(퍼포먼스 튜닝 완료)을 기준으로 검색해야 하는 경우 PHP보다 훨씬 빠르고 장소 검색 거리도 MySQL이 훨씬 빨라야 합니다(찾지 않는 경우).검색할 필요가 없는 데이터는 JSON, BLOB 또는 정말로 필요하다고 생각되는 다른 형식으로 저장할 수 있습니다.

액세스해야 하는 데이터는 JSON으로 매우 쉽게 저장됩니다(예: 기본 건당 청구서 시스템).이들은 RDBMS의 이점을 전혀 얻지 못하고 HTML 폼 구조가 올바르면 json_encoding($_POST['entires')만으로 JSON에 저장할 수 있습니다.

당신이 MongoDB를 사용하고 있는 것은 기쁘고, 그것이 당신에게 계속 도움이 되기를 바라지만, MySQL이 항상 당신의 레이더에서 벗어나기를 기대하지는 않습니다. 당신의 앱이 복잡해짐에 따라 당신은 몇 가지 기능이나 기능을 위해 RDBMS를 필요로 할 수 있습니다(아카이브된 데이터나 비즈니스 보고서를 폐기하기 위해서라도 마찬가지입니다).

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().섹션 12.16.2 "JSON 값을 생성하는 함수"를 참조하십시오.
  2. JSON 값을 검색하는 함수: JSON_CONTENS(), JSON_CONTENS_PATH(), JSON_EXTRACT(), JSON_KEYS() 및 JSON_SEARCH().섹션 12.16.3 "JSON 값을 검색하는 함수"를 참조하십시오.
  3. JSON 값을 변경하는 함수: JSON_APPEND(), JSON_ARRAY_APPEND(), JSON_ARRAY_INSERT(), JSON_QUOTE(), JSON_REMOVE(), JSON_REPLACE(교환), JSON_SET(UN) 및 JSON_SET(UN)섹션 12.16.4 "JSON 값을 수정하는 함수"를 참조하십시오.
  4. JSON 값에 대한 정보를 제공하는 함수: JSON_DEFTH(), JSON_LENGH(), JSON_TYPE() 및 JSON_VALID().섹션 12.16.5 "JSON 값 속성을 반환하는 함수"를 참조하십시오.

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

-> 및 JSON_EXTRACT()에 대한 자세한 내용은 섹션 12.16.3의 "JSON 값을 검색하는 함수"를 참조하십시오.MySQL 5.7에서 JSON 경로 지원에 대한 자세한 내용은 JSON 값 검색 및 수정을 참조하십시오.보조 인덱스 및 가상 생성 열을 참조하십시오.

상세 정보:

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

CouchDB와 MySQL은 매우 다른 두 동물이다.JSON은 CouchDB에 데이터를 저장하는 기본 방법입니다.MySQL에서는 JSON 데이터를 단일 필드에 텍스트로 저장하는 것이 가장 좋습니다.이렇게 하면 RDBMS에 저장하려는 목적이 완전히 상실되고 모든 데이터베이스 트랜잭션이 크게 복잡해집니다.

하지 마.

FriendFeed는 MySQL 위에서 매우 커스텀 스키마를 사용하고 있는 것 같습니다.실제로 무엇을 저장하느냐에 따라 다릅니다.데이터베이스 시스템을 악용하는 방법에 대한 명확한 답은 거의 없기 때문에 고객에게는 의미가 있습니다.이 기사는 매우 오래되었고, Mongo와 Couch에 대한 그들의 주된 이유는 미성숙했기 때문에, MySQL이 당신을 위해 그것을 잘라주지 않는다면 나는 이 두 가지를 다시 평가할 것이다.그들은 지금쯤 많이 자랐어야 했다.

json 문자는 스토리지에 관한 한 특별한 것이 아닙니다.예를 들어 다음과 같은 문자입니다.

{ ,} ,[ ,] ,' ,a-z ,0-9한 것은 할 수 있습니다. 별로 특별한 것은 아니고 텍스트로 저장할 수 있습니다.

당신이 갖게 될 첫 번째 문제는 이것이다.

{profile_id: 22, 사용자 이름: '로버트', 비밀번호: 'skhgeht893htgn34ythg9er' }

데이터베이스에 저장된 것은 mysql을 위한 jsondecode를 개발하지 않는 한 업데이트하기 쉽지 않습니다.

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

따라서 먼저 json을 선택하고, 디코딩하고, 변경하고, 업데이트해야 하기 때문에 이론적으로 적절한 데이터베이스 구조를 구축하는 데 더 많은 시간을 할애할 수 있습니다.

데이터를 저장하기 위해 json을 사용하지만 자주 업데이트되지 않는 Meta Data만 사용하고 사용자 고유의 데이터는 아닙니다.예를 들어 사용자가 게시물을 추가하고 해당 게시물에 이미지를 추가하여 이미지를 해석하고 엄지손가락을 만든 다음 엄지손가락 URL을 json 형식으로 사용합니다.

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

어레이나 기타 오브젝트는 고려하지 않고 기본 데이터 유형만 고려합니다.4개의 컬럼 인스턴스를 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으로 인코딩된 단일 텍스트 필드에 저장하는 것이 좋습니다.

이를 통해 데이터 모델을 크게 단순화할 수 있습니다.그러나 Robert Pitt가 언급한 바와 같이 이 데이터를 정규화된 다른 데이터와 결합할 수 있을 것으로 기대하지는 마십시오.

오래된 질문이지만, 구글 검색 결과 상단에서 확인할 수 있기 때문에 질문 후 4년 후에 새로운 답변을 추가하는 것은 의미가 있다고 생각합니다.

우선 JSON을 RDBMS에 저장하는 것이 더 잘 지원됩니다.PostgreSQL로 전환하는 것을 검토해 주십시오(MySQL은 버전 5.7 이후 JSON을 지원했습니다).포스트그레SQL은 MySQL과 매우 유사한 SQL 명령을 사용합니다.단, 더 많은 기능을 지원합니다.추가된 기능 중 하나는 JSON 데이터 유형을 제공하고 이제 저장된 JSON을 쿼리할 수 있다는 것입니다.(일부 참조) 예를 들어 php에서 PDO를 사용하거나 Larabel에서 웅변을 사용하는 등 프로그램에서 직접 쿼리를 작성하지 않으면 Postgre를 설치하는 것만으로 충분합니다.SQL을 사용하여 데이터베이스 연결 설정을 변경합니다.코드를 변경할 필요도 없습니다.

대부분의 경우 다른 답변에서 제시된 바와 같이 데이터를 JSON으로 RDBMS에 직접 저장하는 것은 좋은 생각이 아닙니다.하지만 몇 가지 예외가 있습니다.제가 생각할 수 있는 한 가지 상황은 링크된 엔트리의 수가 가변적인 필드입니다.

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

태그를 JSON으로 블로그 투고테이블에 저장함으로써 동일한 액션은 1개의 테이블 검색만 필요로 합니다.그러면 사용자는 블로그 투고를 보다 빠르게 편집할 수 있지만, 태그에 링크된 투고를 보고하거나 태그로 검색할 경우 성능이 저하됩니다.

데이터베이스를 정규화하지 않을 수도 있습니다.데이터를 복제하여 저장함으로써 두 가지 방법을 모두 활용할 수 있습니다.데이터 저장에 조금 더 많은 시간과 더 많은 스토리지 공간이 필요합니다(컴퓨팅 파워의 증가에 비해 비용이 저렴합니다).

이 점을 고려해야 할 이유는 다음 두 가지뿐입니다.

  • 표준화된 접근 방식으로는 성능이 충분하지 않습니다.
  • 특정 유동성/변화 데이터를 쉽게 모델링할 수 없습니다.

저는 여기에 저만의 접근법에 대해 조금 썼습니다.

NoSQL 데이터스토어를 사용하여 어떤 확장성 문제가 발생했습니까?

(상위 답변 참조)

JSON조차 속도가 빠르지 않았기 때문에 커스텀 텍스트 형식의 접근 방식을 사용했습니다.계속 잘 작동하고 있습니다.

MongoDB와 같은 것을 사용하지 않는 이유가 있습니까? (MySQL이 "필수"일 수 있습니다.그냥 궁금해서)

JSON 배열의 키를 열에 저장/업데이트하는 함수와 JSON 값을 가져오는 다른 함수가 있습니다.이 함수는 JSON 배열을 저장하는 열 이름을 json으로 가정하여 생성됩니다.PDO를 사용하고 있습니다.

저장/업데이트 기능

function save($uid, $key, $val){
 global $dbh; // The PDO object
 $sql = $dbh->prepare("SELECT `json` FROM users WHERE `id`=?");
 $sql->execute(array($uid));
 $data      = $sql->fetch();
 $arr       = json_decode($data['json'],true);
 $arr[$key] = $val; // Update the value
 $sql=$dbh->prepare("UPDATE `users` SET `json`=? WHERE `id`=?");
 $sql->execute(array(
   json_encode($arr), 
   $uid
 ));
}

여기서 $uid는 사용자의 ID, $key - 업데이트할 JSON 키이며 값은 $val로 표시됩니다.

가치 함수 가져오기

function get($uid, $key){
 global $dbh;
 $sql = $dbh->prepare("SELECT `json` FROM `users` WHERE `id`=?");
 $sql->execute(array($uid));
 $data = $sql->fetch();
 $arr  = json_decode($data['json'], true);
 return $arr[$key];
}

여기서 $key는 값이 필요한 JSON 어레이의 키입니다.

이 질문에 대답하는 모든 사람은 @deceze를 제외하고 중요한 한 가지 문제를 놓치고 있는 것 같습니다.그 일에 적합한 도구를 사용합니다.관계형 데이터베이스에 거의 모든 유형의 데이터를 저장하도록 강제할 수 있으며 Mongo에게 관계형 데이터를 처리하도록 강제할 수 있습니다. 단, 어떤 대가를 치르더라도 마찬가지입니다.결과적으로 스키마 설계에서 애플리케이션 코드에 이르기까지 모든 개발 및 유지 보수 수준에서 복잡성이 발생하게 됩니다.또한 성능 저하되는 것은 말할 것도 없습니다.

2014년에는 특정 유형의 데이터를 매우 잘 처리하는 많은 데이터베이스 서버에 액세스할 수 있습니다.

  • Mongo(문서 저장소)
  • Redis(주요 가치 데이터 스토리지)
  • MySQL/Maria/PostgreSQL/Oracle 등 (관계 데이터)
  • CouchDB(JSON)

랍비르MQ나 카산드라 같은 다른 사람들이 그리웠을 거야요점은 저장해야 하는 데이터에 적합한 도구를 사용하라는 것입니다.

다양한 데이터의 저장 및 취득이 매우 신속하게 필요한 경우(또한 그렇지 않은 사용자도 마찬가지) 애플리케이션에 여러 데이터 소스를 사용하는 것을 주저하지 마십시오.대부분의 일반적인 웹 프레임워크는 여러 데이터 소스(레일, Django, Grails, Cake, Zend 등)를 지원합니다.이 전략은 애플리케이션의 특정 영역인 ORM 또는 애플리케이션의 데이터 소스 인터페이스로 복잡성을 제한합니다.

MySQL에서 JSON 저장을 위한 초기 지원이 MySQL 5.7.7 JSON labs 릴리스(linux 바이너리, 소스)에 추가되었습니다.2013년에 공개된 일련의 JSON 관련 사용자 정의 기능에서 성장한 것으로 보인다.

이 초기 네이티브 JSON 지원은 INSERT에 대한 JSON 검증을 포함하여 매우 긍정적인 방향으로 진행되고 있는 것으로 보입니다.INSERT는 JSN_EXTRACT 함수가 모든 액세스에 대해 구문 분석하지 않고 바이너리 검색을 수행할 수 있도록 하는 프리암블에 룩업 테이블을 포함하는 최적화된 바이너리 스토리지 형식입니다.또한 특정 JSON 데이터 유형을 처리하고 쿼리하기 위한 다양한 새로운 기능도 있습니다.

CREATE TABLE users (id INT, preferences JSON);

INSERT INTO users VALUES (1, JSN_OBJECT('showSideBar', true, 'fontSize', 12));

SELECT JSN_EXTRACT(preferences, '$.showSideBar') from users;

+--------------------------------------------------+
| id   | JSN_EXTRACT(preferences, '$.showSideBar') |
+--------------------------------------------------+
| 1    | true                                      |
+--------------------------------------------------+

에는 이미 하기 위해 을 단일 IMHO로 이 좋습니다.많은 SQL 데이터베이스에는 이미 사용자 테이블이 있으며 진화하는 사용자 프리퍼런스에 대응하기 위해 스키마를 끝없이 변경하는 것이 아니라 단일 JSON 컬럼을 1개로 만듭니다.JOIN★★★★★★★ 개별의 아이템에 같습니다.특히 개별 항목에 대해 조회할 필요가 없을 것 같습니다.

아직 초기 단계이지만 MySQL 서버 팀은 블로그에서 변경 사항을 잘 전달하고 있습니다.

JSON은 Postgre의 유효한 데이터 유형입니다.SQL 데이터베이스도 마찬가지입니다.그러나 MySQL 데이터베이스는 아직 공식적으로 JSON을 지원하지 않습니다.베이킹 중: http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/

또한 일부 데이터를 데이터베이스의 문자열에 직렬화하는 것이 더 낫다는 많은 유효한 사례가 있다는 것에 동의합니다.주된 이유는 정기적으로 쿼리되지 않고 자체 스키마가 변경될 수 있기 때문입니다. 이에 따라 데이터베이스 스키마를 변경하지 않을 수 있습니다.두 번째 이유는 시리얼라이즈된 문자열이 외부 소스로부터 직접 전송되는 경우 이들 문자열을 모두 해석하고 사용하지 않는 한 어떤 비용도 데이터베이스에 입력할 필요가 없기 때문입니다.새로운 MySQL 릴리즈가 JSON을 지원하기를 기다리겠습니다. 그러면 다른 데이터베이스 간에 전환이 더 쉬워지기 때문입니다.

늦은 감이 있지만 테이블을 정규화한 후 데이터를 텍스트 값으로 JSON에 저장하는 하이브리드 방식을 사용한 적이 있습니다.예를 들어 RDBMS 정규화 규칙에 따라 4개의 테이블에 데이터를 저장합니다.그러나 동적 스키마를 수용하기 위한 네 번째 표에서는 데이터를 JSON 형식으로 저장합니다.데이터를 취득하고 싶을 때마다 JSON 데이터를 취득하고 해석하여 Java로 표시합니다.이것은 지금까지도 유효했습니다.또한 표의 json 데이터로 변환한 필드를 ETL을 사용하여 정규화된 방법으로 인덱싱할 수 있습니다.이것에 의해, 유저는 애플리케이션 작업중에, 최소한의 지연에 직면하게 되어, 필드는 데이터 분석등을 위해서 RDBMS 친화적인 포맷으로 변환됩니다.MYSQL(5.7+)을 사용하면 JSON의 해석도 가능하므로 RDBMS와 NOSQL 데이터베이스의 이점을 모두 얻을 수 있습니다.

프로젝트의 모든 것을 기록하기 위해 json을 사용합니다.실제로 3개의 테이블을 사용합니다.하나는 json의 데이터, 하나는 json 구조의 각 메타데이터의 인덱스(각 메타는 고유 ID로 인코딩됨), 다른 하나는 세션 사용자를 위해 사용합니다.그것뿐입니다.이 초기 코드 상태에서는 벤치마크를 수량화할 수 없지만 예를 들어 사용자 뷰(내부 인덱스 참여)를 사용하여 카테고리(또는 사용자로서 어떤 것이든...)를 취득했습니다.그것은 매우 느렸습니다(매우 느리고 mysql에서 사용되는 뷰는 좋은 방법이 아닙니다).이 구조에서는 검색 모듈이 내가 원하는 것은 무엇이든 할 수 있지만, 이 완전 json 데이터 레코드의 컨셉에서는 mongodb가 더 효율적일 것이라고 생각합니다.예를 들어, 나는 카테고리 트리를 만들기 위해 사용자 뷰와 브레드 크럼, 마이 갓! 너무 많은 쿼리가 실행되었다! apache 자체를! 그리고 사실 이 작은 웹사이트에서는 트리와 브레드 크럼을 생성하는 php를 사용한다.데이터의 추출은 검색 모듈(인덱스만 사용한다)에 의해서만 이루어진다.필요에 따라서, 모든 인덱스를 파기해, 각 데이터로 재생성하거나, 반대로 모든 데이터(json)를 파기해, 인덱스 테이블만으로 재생성하거나 할 수 있습니다.제 프로젝트는 아직 어려서 php와 mysql에서 실행 중이지만, 가끔은 노드 js와 mongodb를 사용하는 것이 이 프로젝트에서 더 효율적일 것입니다.

만약 당신이 할 수 있다고 생각한다면 json을 사용하세요. 왜냐하면 당신은 할 수 있기 때문입니다.그리고 만약 그것이 실수였다면 잊어버리세요; 좋은 선택이든 나쁜 선택이든 시도해 보세요!

낮다

프랑스어 사용자

JSON을 mysql 데이터베이스에 저장하는 것은 실제로 RDBMS의 사용 목적에 어긋난다고 생각합니다.어느 시점에서 조작되거나 보고되는 데이터에는 사용하지 않습니다.사용 방법에 따라 복잡성이 가중될 뿐만 아니라 퍼포먼스에 영향을 미치기 때문입니다.

하지만, 나는 다른 누군가가 실제로 이것을 할 수 있는 가능한 이유를 생각해냈는지 궁금했다.로깅을 위해 예외를 두려고 합니다.제 경우 파라미터와 에러의 양이 다양한 요청을 로그에 기록합니다.이 경우 요구 유형 및 요구 자체에 다른 값의 JSON 문자열이 있는 테이블을 사용합니다.

위의 경우 요청은 기록되며 JSON 문자열 필드 내에서 조작 또는 인덱싱되지 않습니다.다만, 보다 복잡한 환경에서는, 이러한 종류의 데이터를 보다 의도적인 것으로 사용해, 그 시스템에 보존하려고 합니다.다른 사람들이 말했듯이, 그것은 여러분이 무엇을 달성하려고 하는가에 달려있지만, 표준을 따르는 것은 항상 장수와 신뢰성에 도움이 됩니다.

다음 요지를 사용할 수 있습니다.https://gist.github.com/AminaG/33d90cb99c26298c48f670b8ffac39c3

서버에 인스톨 한 후(super가 아닌 root 권한만 있으면 됩니다) 다음과 같이 할 수 있습니다.

select extract_json_value('{"a":["a","2"]}','(/a)')

은 반환될 이다.a 2이것을 사용하면 JSON 내의 모든 것을 반환할 수 있습니다.MySQL 5.1, 5.2, 5.6을 사용하다서버에 바이너리를 인스톨 할 필요는 없습니다.

프로젝트에 하고 있다common-schemahttps://code.google.com/archive/p/common-schema/ 에서 동작하고 있습니다.

언급URL : https://stackoverflow.com/questions/3564024/storing-data-in-mysql-as-json

반응형