My article “SQL vs NoSQL: The Differences” noted that the line between SQL and NoSQL databases has become increasingly blurred, with each camp adopting features from the other. MySQL 5.7+ InnoDB databases and PostgreSQL 9.2+ both directly support JSON document types in a single field. In this article, we’ll examine the MySQL 8.0 JSON implementation in more detail. Show Note that any database will accept JSON documents as a single string blob. However, MySQL and PostgreSQL support validated JSON data in real key/value pairs rather than a basic string. Just Because You Can Store JSON …… it doesn’t follow you should. Normalization is a technique used to optimize the database structure. The First Normal Form (1NF) rule governs that every column should hold a single value — which is clearly broken by storing multi-value JSON documents. If you have clear relational data requirements, use appropriate single-value fields. JSON should be used sparingly as a last resort. JSON value fields can’t be indexed, so avoid using it on columns which are updated or searched regularly. In addition, fewer client applications support JSON and the technology is newer, so it could be less stable than other types. That said, there are good JSON use cases for sparsely populated data or custom attributes. Create a Table With a JSON FieldConsider a shop selling books. All books have an ID, ISBN, title, publisher, number of pages and other clear relational data. Presume you want to add any number of category tags to each book. You could achieve this in SQL using:
It’ll work, but it’s cumbersome and considerable effort for a minor feature. Therefore, you can define a tags JSON field in your MySQL database’s book table:
Note that JSON columns can’t have a default value, be used as a primary key, be used as a foreign key, or have an index. You can create secondary indexes on generated virtual columns, but it’s easier and more practical to retain a value in a separate field if indexes are required. Adding JSON DataWhole JSON documents can be passed in INSERT or UPDATE statements. For example, our book tags can be passed as an array (inside a string):
JSON can also be created with these:
The allows you to check JSON value types. It should return OBJECT, ARRAY, a scalar type (INTEGER, BOOLEAN, etc), NULL, or an error. For example:
The returns 1 if the JSON is valid or 0 otherwise:
Attempting to insert an invalid JSON document will raise an error and the whole record will not be inserted/updated. Searching JSON DataThe accepts the JSON document being searched and another to compare against. It returns 1 when a match is found. For example:
The similar returns the path to the given match or NULL when there’s no match. It’s passed the JSON document being searched, 6 to find the first match, or 7 to find all matches, and a search string (where 8 matches any number of characters and 9 matches one character in an identical way to ). For example:
JSON PathsA JSON path targets values and can be used to extract or modify parts of a JSON document. The demonstrates this by extracting one or more values:
All path definitions start with a 1 followed by other selectors:
The following examples refer to the following JSON document: 0Example paths:
Extracting JSON Paths in QueriesYou could extract the name and first tag of your book table using the query: 1For a more complex example, presume you have a user table with JSON profile data. For example: idnameprofile1Craig{ “email”: [“[email protected]”, “[email protected]”], “twitter”: “@craigbuckler” }2SitePoint{ “email”: [], “twitter”: “@sitepointdotcom” }You can extract the Twitter name using a JSON path. For example: 2You could use a JSON path in the WHERE clause to only return users with a Twitter account: 3Modifying Part of a JSON DocumentThere are several MySQL functions to modify parts of a JSON document using path notation. These include:
You can therefore add a “technical” tag to any book which already has a “JavaScript” tag: 4Further InformationThe MySQL manual provides further information about the JSON data type and the associated JSON functions. Again, I urge you not to use JSON unless it’s absolutely necessary. You could emulate an entire document-oriented NoSQL database in MySQL, but it would negate many benefits of SQL, and you may as well switch to a real NoSQL system! That said, JSON data types might save effort for more obscure data requirements within an SQL application. Share This ArticleCraig Buckler Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler. |