When can I save JSON or XML data in an SQL Table

前端 未结 8 1685
星月不相逢
星月不相逢 2020-11-27 12:04

When using SQL or MySQL (or any relational DB for that matter) - I understand that saving the data in regular columns is better for indexing sake a

相关标签:
8条回答
  • 2020-11-27 12:06

    Json's are not great in relationional db's. If you unfold the json into columns and store in a db , it's great but storing a json as a blob is next to using it as data archival system.

    There could be several reasons for not unfolding a json and storing it in a single column but the decision would have been taken as the values in that json field would not be used for any querying (or the values have been already unfolded into columns).

    Also , most of the json processing if at all the field was queried would be outside the sql environment as sql is just not meant for json processing. The real question then becomes , where do i store this json, do i just let it be as flat files and when required query them via some other system (spark/hive/etc).

    I would agree with your DB artist , don't use RDBMS for archival. There are cheaper options. Also json blobs can get huge and can start bogging down the DB disk space with time.

    0 讨论(0)
  • 2020-11-27 12:06

    PostgreSQL has a built-in json and jsonb data type

    • json
    • json vs jsonb

    These are a few examples:

    CREATE TABLE orders (
     ID serial NOT NULL PRIMARY KEY,
     info json NOT NULL
    );
    
    INSERT INTO orders (info)
    VALUES
     (
     '{ "customer": "Lily Bush", "items": {"product": "Diaper","qty": 24}}'
     ),
     (
     '{ "customer": "Josh William", "items": {"product": "Toy Car","qty": 1}}'
     ),
     (
     '{ "customer": "Mary Clark", "items": {"product": "Toy Train","qty": 2}}'
     );
    

    PostgreSQL provides two native operators -> and ->> to query JSON data.

    The operator -> returns JSON object field by key.

    The operator ->> returns JSON object field by text.

    SELECT
     info -> 'customer' AS customer
    FROM
     orders;
    
    SELECT
     info ->> 'customer' AS customer
    FROM
     orders
    WHERE
     info -> 'items' ->> 'product' = 'Diaper'
    
    0 讨论(0)
  • 2020-11-27 12:08

    The "golden rule" I use, in a hand-wavey sort of way, is that if I need JSON in its raw format, it's okay to store. If I have to make a special point of parsing it, then it's not.

    For instance, if I'm creating an API that sends out raw JSON, and for whatever reason this value isn't going to change, then it's okay to store it as raw JSON. If I have to parse it, change it, update it, etc... then not so much.

    0 讨论(0)
  • 2020-11-27 12:10

    New SQL Server provides functions for processing JSON text. Information formatted as JSON can be stored as text in standard SQL Server columns and SQL Server provides functions that can retrieve values from these JSON objects.

        DROP TABLE IF EXISTS Person
    
     CREATE TABLE Person 
     ( _id int identity constraint PK_JSON_ID primary key,
     value nvarchar(max)
     CONSTRAINT [Content should be formatted as JSON]
     CHECK ( ISJSON(value)>0 )
     )
    

    This simple structure is similar to the standard NoSQL collection that you can create in NoSQL databases (e.g. Azure DocumentDB or MongoDB) where you just have key that represents ID and value that represents JSON.

    Note that NVARCHAR is not just a plain text. SQL Server has built-in text compressions mechanism that can transparently compress data stored on disk. Compression depends on language and can go up to 50% depending on your data (see UNICODE compression ).

    The key difference between SQL server and other plain NoSQL databases is that SQL Server enables you to use hybrid data model where you can store several JSON objects in the same “collection” and combine them with regular relational columns.

    As an example, imagine that we know that every person in your collection will have FirstName and LastName, and that you can store general information about the person as one JSON object, and phone numbers/email addresses as separate objects. In SQL Server 2016 we can easily create this structure without any additional syntax:

    DROP TABLE IF EXISTS Person
    
    CREATE TABLE Person (
    
     PersonID int IDENTITY PRIMARY KEY,
    
     FirstName nvarchar(100) NOT NULL,
    
     LastName nvarchar(100) NOT NULL,
    
     AdditionalInfo nvarchar(max) NULL,
    
     PhoneNumbers nvarchar(max) NULL,
    
     EmailAddresses nvarchar(max) NULL
     CONSTRAINT [Email addresses must be formatted as JSON array]
     CHECK ( ISJSON(EmailAddresses)>0 )
    
     )
    

    Instead of single JSON object you can organize your data in this “collection”. If you do not want to explicitly check structure of each JSON column, you don’t need to add JSON check constraint on every column (in this example I have added CHECK constraint only on EmailAddresses column).

    If you compare this structure to the standard NoSQL collection, you might notice that you will have faster access to strongly typed data (FirstName and LastName). Therefore, this solution is good choice for hybrid models where you can identify some information that are repeated across all objects, and other variable information can be stored as JSON. This way, you can combine flexibility and performance.

    If you compare this structure with the schema of Person table AdventureWorks database, you might notice that we have removed many related tables.

    Beside simplicity of schema, your data access operations will be simpler compared to complex relational structure. Now you can read single table instead of joining several tables. When you need to insert new person with related information (email addresses, phone numbers) you can insert a single record in one table instead of inserting one record in AdventureWorks Person table, taking identity column to find foreign key that will be used to store phones, email addresses, etc. In addition, in this model you can easily delete single person row without cascade deletes using foreign key relationships.

    NoSQL databases are optimized for simple, read, insert, and delete operations – SQL Server 2016 enables you to apply the same logic in relational database.

    JSON constraints In the previous examples, we have seen how to add simple constraint that validates that text stored in the column is properly formatted. Although JSON do not have strong schema, you can also add complex constraints by combining functions that read values from JSON and standard T-SQL functions:

    ALTER TABLE Person
     ADD CONSTRAINT [Age should be number]
     CHECK ( ISNUMERIC(JSON_VALUE(value, '$.age'))>0 )
    
     ALTER TABLE Person
     ADD CONSTRAINT [Person should have skills]
     CHECK ( JSON_QUERY(value, '$.skills') IS NOT NULL)
    First constraint will take the value of $.age property and check is this numeric value. Second constraint will try to find JSON object in $.skills property and verify that it exists. The following INSERT statements will fail due to the violation of constraints:
    
    
    
    INSERT INTO Person(value)
     VALUES ('{"age": "not a number", "skills":[]}')
    
     INSERT INTO Person(value)
     VALUES ('{"age": 35}')
    

    Note that CHECK constraints might slow down your insert/update processes so you might avoid them if you need faster write performance.

    Compressed JSON storage If you have large JSON text you can explicitly compress JSON text using built-in COMPRESS function. In the following example compressed JSON content is stored as binary data, and we have computed column that decompress JSON as original text using DECOMPRESS function:

    CREATE TABLE Person
    
     ( _id int identity constraint PK_JSON_ID primary key,
    
     data varbinary(max),
    
     value AS CAST(DECOMPRESS(data) AS nvarchar(max))
    
     )
    
    
    
     INSERT INTO Person(data)
    
     VALUES (COMPRESS(@json))
    

    COMPRESS and DECOMPRESS functions use standard GZip compression. If your client can handle GZip compression (e.g browser that understands gzip content), you can directly return compressed content. Note that this is performance/storage trade-off. If you frequently query compressed data you mig have slower performance because text must be decompressed each time.

    Note: JSON functions are available only in SQL Server 2016+ and Azure SQL Database.

    More can be read from the source of this article

    https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/23/storing-json-in-sql-server/

    0 讨论(0)
  • 2020-11-27 12:14

    I'll wave my magic wand. Poof! Golden Rules on use of JSON:

    • If MySQL does not need to look inside the JSON, and the application simply needs a collection of stuff, then JSON is fine, possibly even better.

    • If you will be searching on data that is inside and you have MariaDB 10.0.1 or MySQL 5.7 (with a JSON datatype and functions), then JSON might be practical. MariaDB 5.3's "Dynamic" columns is a variant on this.

    • If you are doing "Entity-Attribute-Value" stuff, then JSON is not good, but it is the least of several evils. http://mysql.rjweb.org/doc.php/eav

    • For searching by an indexed column, not having the value buried inside JSON is a big plus.

    • For searching by a range on an indexed column, or a FULLTEXT search or SPATIAL, JSON is not possible.

    • For WHERE a=1 AND b=2 the "composite" index INDEX(a,b) is great; probably can't come close with JSON.

    • JSON works well with "sparse" data; INDEXing works, but not as well, with such. (I am referring to values that are 'missing' or NULL for many of the rows.)

    • JSON can give you "arrays" and "trees" without resorting to extra table(s). But dig into such arrays/trees only in the app, not in SQL.

    • JSON is worlds better than XML. (My opinion)

    • If you do not want to get into the JSON string except from the app, then I recommend compressing (in the client) it an storing into a BLOB. Think of it like a .jpg -- there's stuff in there, but SQL does not care.

    State your application; maybe we can be more specific.

    0 讨论(0)
  • 2020-11-27 12:18

    This is too long for a comment.

    If it were "absolutely wrong", then most databases would not support it. Okay, most databases support commas in the FROM clause and I view that as "absolutely wrong". But support for JSON is new development, not a backward-compatible "feature".

    One obvious case is when the JSON struct is simply a BLOB that is passed back to the application. Then there is no debate -- other then the overhead of storing JSON, which is unnecessarily verbose for structured data with common fields in every record.

    Another case is the "sparse" columns case. You have rows with many possible columns, but these vary from row to row.

    Another case is when you want to store "nested" records in a record. JSON is powerful.

    If the JSON has common fields across records that you want to query on, then you are usually better off putting these in proper database columns. However, data is complicated and there is a place for formats such as JSON.

    0 讨论(0)
提交回复
热议问题