The document provides an overview of the MySQL Document Store, which allows storing and querying JSON documents within MySQL tables without requiring SQL. It is built on the MySQL JSON data type and X DevAPI. Key features highlighted include the ability to work with both relational tables and document collections together using various programming languages, transactions, and casting collections as tables. The document store is available in MySQL 5.7 and 8 via a plug-in.
2. Safe
Harbor
Agreement
2
"THE FOLLOWING IS INTENDED TO OUTLINE
OUR GENERAL PRODUCT DIRECTION. IT IS
INTENDED FOR INFORMATION PURPOSES
ONLY, AND MAY NOT BE INCORPORATED
INTO ANY CONTRACT. IT IS NOT A
COMMITMENT TO DELIVER ANY MATERIAL,
CODE, OR FUNCTIONALITY, AND SHOULD
NOT BE RELIED UPON IN MAKING
PURCHASING DECISIONS. THE
DEVELOPMENT, RELEASE, AND TIMING OF
ANY FEATURES OR FUNCTIONALITY
DESCRIBED FOR ORACLE'S PRODUCTS
REMAINS AT THE SOLE DISCRETION OF
ORACLE."
6. Developers
and DBAs
see data
differently
6
mysql-js> db.countryinfo.find("_id='USA'")
[
{
"GNP": 8510700,
"IndepYear": 1776,
"Name": "United States",
"_id": "USA",
"demographics": {
"LifeExpectancy": 77.1,
"Population": 278357000
},
"geography": {
"Continent": "North America",
"Region": "North America",
"SurfaceArea": 9363520
},
"government": {
"GovernmentForm": "Federal Republic",
"HeadOfState": "George W. Bush"
}
}
]
1 document in set (0.01 sec)
mysql-js>
7. Developers Developers have a much more complex job compared to a
decade ago
7
▪ Start coding first, design later (ready, fire, aim!)
▪ Scope Creep, Mission Creep
▪ New flashy tech pushed down from Management
▪ New flashy tech pushed to keep resume current
▪ Legacy code
▪ Learning curve (ever steepening)
▪ Continuous fire fighting
8. DBAs
(& Devops)
DBAs have a much more complex job compared to a decade
ago
8
▪ Keep data safe
▪ Stability
▪ CI
▪ Flexibility
▪ Regulations & policies for data retention
▪ Maximize uptime (no window for maintenance)
▪ Ripple changes that never end
▪ More demands , less $$$
▪ Relational model fits so many business needs
9. Structed Query
Language
1. Descriptive Language
2. DML and DDL
3. Requires:
a. Knowledge of sets
b. Knowledge of the data
4. Hard to tell if a query is
good just by looking at it
1. No ‘gut feeling’ about query
2. EXPLAIN
9
SQL was designed in the 1970s to
minimize data duplication (disks were
very expensive) and allows the access
of many records in one command
without have to specify how to get to
it.
10. 10
Roughly 2% of
developers have
formal training in
SQL, Relational
Theory, or sets(my survey)
And 100%
of the rest
wonder
why their
queries
stink!
11. ORMs
Developers might
use a Object
Relation Mapper
to map between
RDMS and
objects in code.
Extra layer of
confusion.
Extra inclination
on learning
curve.
11
12. How do you
provide for both sets
of needs?
12
What if there was a
way to provide both
SQL and NoSQL
on one stable
platform that has
proven stability on
well known
technology?
14. Built on the
MySQL
JSON Data
type
and
Proven
MySQL
Server
Technology
Provides a schema flexible JSON document store
No SQL required
No need to define all possible attributes, tables, etc.
Uses new X DevAPI
MySQL 5.7 & 8
Can leverage generated columns to extract JSON values into
materialized columns that can be indexed for fast SQL searches.
Documents can be ~1GB
It is a column in a row of a table
Allows use of modern programming styles
No more embedded strings of SQL in your code
Easy to read
Also works with relational tables
Proven MySQL Technology
14
15. X DevAPI • Connectors for
• C++, Java, .Net, Node.JS, Python, JavaScript,
PHP
• More on the way
• New MySQL Shell
• Command Completion
• Python, JavaScript & SQL modes
• Admin functions
• A new high-level session concept that can scale
from single MySQL Server to a multiple server
environment.
• Non-blocking, asynchronous calls follow common
language patterns
• Modern practices and syntax styles are used to get away
from traditional SQL-String-Building
15
16. MySQL
Document
Store
Installation
mysqlsh -u user -h localhost --classic --dba enableXProtocol
OR
$mysql –u root –p
mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so‘ ; *
16* .dll for windows instead of .so
17. mysqlsh
17
▪ New command line
client built on X
DevAPI (old client is
not going away
anytime soon).
▪ Visually appealing
▪ Command
Completion
▪ Three modes
- Python
- JavaScript
- SQL
18. Login with
MySQL
Shell
18
MySQL Shell 8.0.5
Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help' or '?' for help; 'quit' to exit.
MySQL JS> connect root@localhost/world_x
Creating a session to 'root@localhost/world_x'
Enter password: ******
Your MySQL connection id is 4 (X protocol)
Server version: 5.7.21-log MySQL Community Server (GPL)
Default schema `world_x` accessible through db.
Fetching schema names for auto-completion... Press ^C to stop.
MySQL [localhost+/world_x] JS>
27. Python
import mysqlx
# Connect to server on localhost
session = mysqlx.get_session({
'host': 'localhost',
'port': 33060,
'user': 'dave',
'password': 'S3cR3T!',
'ssl-mode' : mysqlx.SSLMode.DISABLED #Remove this line if SSL enabled
})
schema = session.get_schema('world_x')
# Use the collection 'countryinfo'
collection = schema.get_collection('countryinfo')
# Specify which document to find with Collection.find()
result = collection.find('_id like :param').bind('param',
'USA').execute()
# Print document
docs = result.fetch_all()
print('id: {0}'.format(docs[0]['Name']))
27
28. Node.JS
// Simple example to grab one record and print it
const mysqlx = require('@mysql/xdevapi');
const options = {
host: 'localhost', port: 33060, dbUser: 'dave', dbPassword:
'S3cR3t!!'
};
mysqlx
.getSession(options)
.then (session => {
var schema = session.getSchema('world_x');
//equivalent of SELECT doc FROM countryinfo where _id = 'USA'
var coll = schema.getCollection('countryinfo');
var query = "$._id == 'USA'";
// Print doc
return Promise.all([
coll.find(query).execute(function (doc) {
console.log(doc);
}),
session.close()
]);
})
.catch(err => {
console.log(err.message);
console.log(err.stack);
});
28
29. PHP
#!/usr/bin/php
<?PHP
// Connection parameters
$user = 'dave';
$passwd = 'S3cR3t!';
$host = 'localhost';
$port = '33060';
$connection_uri = 'mysqlx://'.$user.':'.$passwd.'@'.
$host.':'.$port;
echo $connection_uri . "n";
// Connect as a Node Session
$nodeSession =
mysql_xdevapigetNodeSession($connection_uri);
// "USE world_x"
$schema = $nodeSession->getSchema("world_x");
// Specify collection to use
$collection = $schema->getCollection("countryinfo");
// Query the Document Store
$result = $collection->find('_id = "USA"')->fields(['Name
as Country','geography as Geo','geography.Region'])-
>execute();
// Fetch/Display data
$data = $result->fetchAll();
var_dump($data);
?>
29
31. What does a
collection
look like on
the server?
mysql> DESC countryinfo;
+-------+-------------+------+-----+---------+------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+------------------+
| doc | json | YES | | NULL | |
| _id | varchar(32) | NO | PRI | NULL | STORED GENERATED |
+-------+-------------+------+-----+---------+------------------+
2 rows in set (0.02 sec)
mysql> show create table countryinfoG
*************************** 1. row ***************************
Table: countryinfo
Create Table: CREATE TABLE `countryinfo` (
`doc` json DEFAULT NULL,
`_id` varchar(32) GENERATED ALWAYS AS
(json_unquote(json_extract(`doc`,'$._id))) STORED NOT
NULL,
PRIMARY KEY (`_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
31
32. Every document has a unique identifier called the document
ID, which can be thought of as the equivalent of a tables'
primary key. The document ID value can be manually
assigned when adding a document. If no value is assigned, a
document ID is generated and assigned to the document
automatically!
Use getDocumentId() or getDocumentIds() to get _id(s)
32
_id
33. You can also
use the
JavaScript or
Python
modes to
process code
// Connecting to MySQL and working with a Session
var mysqlx = require('mysqlx');
// Connect to a dedicated MySQL server using a connection URL
var mySession = mysqlx.getSession(‘acct:spE!@localhost');
// Get a list of all available schemas
var schemaList = mySession.getSchemas();
print('Available schemas in this session:n');
// Loop over all available schemas and print their name
for (index in schemaList) {
print(schemaList[index].name + 'n');
}
mySession.close();
33
35. Yes, the
MySQL
Document
Store can
work with
relational
tables too!
# Working with Relational Tables
import mysqlx
# Connect to server using a connection URL
mySession = mysqlx.get_session( {
'host': 'localhost', 'port': 33060,
'dbUser': ‘joe', 'dbPassword': ‘ZipL1p!'} )
myDb = mySession.get_schema('test')
# Accessing an existing table
myTable = myDb.get_table('my_table')
# Insert SQL Table data
myTable.insert(['name','birthday','age'])
.values('Sakila', mysqlx.date_value(2000, 5, 27), 16).execute()
# Find a row in the SQL Table
myResult = myTable.select(['_id', 'name', 'birthday'])
.where('name like :name AND age < :age')
.bind('name', 'S%')
.bind('age', 20).execute()
# Print result
print myResult.fetch_all()
35
36. But what about relational tables and
collections together? Eh, Dave?
Huh, huh, huh?
36
37. But what about relational tables and
collections together? Eh, Dave?
Huh, huh, huh?
37
38. // Get the customers collection as a table
var customers = db.getCollectionAsTable('customers');
customers.insert('doc').values('{"_id":"001", "name": "mike"}').execute();
38
You can cast a collection as a table
39. import com.mysql.cj.api.xdevapi.*;
import com.mysql.cj.xdevapi.*;
// Connect to server
Session mySession = new SessionFactory().getSession("mysqlx://10.10.10.192:33060/test?user=betty12;password=Hush!");
Schema db = mySession.getSchema("test");
// Create a new collection
Collection myColl = db.createCollection("my_collection");
// Start a transaction
this.session.startTransaction();
try {
myColl.add("{"name":"Jack", "age":15}", "{"name":"Susanne", "age":24}",
"{"name":"Mike", "age":39}");
this.session.commit();
System.out.println("Data inserted successfully.");
} catch (Exception err) {
// Rollback the transaction in case of an error
this.session.rollback();
// Printing the error message
System.out.println("Data could not be inserted: " + err.getMessage());
}
39
Transactions!
41. Hello!
Nice to meet you
41
Contact info:
▪ www.mysql.com
▪ David.Stokes@Oracle.com
▪ @Stoker
▪ Slides:slideshare.net/davidmstokes
▪ Blog: Elephantdolphin.blogspot.com
▪ Book in preperation now