Copyright © 2014 Oracle and/or its affiliates. All rights reserved. | Introducing the MySQL Document Store Alfredo Kojima – Sr. Dev. Manager Mike Frank – Product Management Director Oracle Oracle ConfidenNal – Internal/Restricted/Highly Restricted
Copyright©2014Oracleand/oritsaffiliates.Allrightsreserved.|
IntroducingtheMySQLDocumentStore
AlfredoKojima–Sr.Dev.ManagerMikeFrank–ProductManagementDirectorOracle
OracleConfidenNal–Internal/Restricted/HighlyRestricted
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
SafeHarborStatementThefollowingisintendedtooutlineourgeneralproductdirecNon.ItisintendedforinformaNonpurposesonly,andmaynotbeincorporatedintoanycontract.Itisnotacommitmenttodeliveranymaterial,code,orfuncNonality,andshouldnotberelieduponinmakingpurchasingdecisions.Thedevelopment,release,andNmingofanyfeaturesorfuncNonalitydescribedforOracle’sproductsremainsatthesolediscreNonofOracle.
2
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
Today’sAgenda
RelaNonalDatabases,DocumentDatabasesandMySQL
MySQLJSONSupport
DocumentUseCases
TheXDevAPI
Ge\ngitallworkingtogether
1
2
3
4
3
5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalDatabases• DataIntegrity– NormalizaNon– Constraints(foreignkeysetc)
• Atomicity,Consistency,IsolaNon,Durability-ACID– TransacNons
• SQL– Powerful,OpNmizableQueryLanguage– DeclarewhatyouwantandtheDBwillfindoutthemostefficientwaytogetittoyou
OracleConfidenNal–Restricted 4
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
Plus…• MySQLhasbeenaroundsince1995• Ubiquitous• Pregymuchastandard• Scalable• Whenthereareissues,theyareknownandunderstood• Largebodyofknowledge,fromsmalltoBIGdeployments
OracleConfidenNal–Restricted 5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
DocumentDatabases
OracleConfidenNal–Restricted 6
• Schemaless– noschemadesign,normalizaNon,foreignkeys,constraints,datatypesetc– fasteriniNaldevelopment
• Flexibledatastructures– nestedarraysandobjects– somedataissimplynaturallyunstructuredorcannotbemodeledefficientlyintherelaNonalmodel(hierarchies,productDBetc)– persistobjectswithoutORMs
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
DocumentDatabases(Cont.)
OracleConfidenNal–Restricted 7
• JSON– Closertothefrontend– "naNve"inJavaScript– Node.jsandfullstackJavaScript
• Easytolearn,easytouse
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalvsDocumentDatabases
Whynotboth?
OracleConfidenNal–Restricted 8
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalDatabases,DocumentDatabasesandMySQL
MySQLJSONSupport
DocumentUseCases
TheXDevAPI
Ge\ngitallworkingtogether
9
1
2
3
4
5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQL5.7:JSONSupport• NaNveJSONdatatype• StoreJSONvalues(objects,arraysandsimplevalues)inMySQLtables• BinaryJSONstorageformat• Conversionfrom"naNve"SQLtypestoandfromJSONvalues• JSONManipulaNonfuncNons– Extractcontents(JSON_EXTRACT,JSON_KEYSetc)– Inspectcontents(JSON_CONTAINSetc)– Modifycontents(JSON_SET,JSON_INSERT,JSON_REMOVEetc)– Createarraysandobjects(JSON_ARRAY,JSON_OBJECT)– Searchobjects(JSON_SEARCH)
OracleConfidenNal–Restricted 10
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQL5.7:JSONSupport(cont.)• InlineSQLJSONpathexpressionsSELECT doc->'$.object.array[0].item' FROM some_table
• Booleanoperators(compareJSONvaluesetc)– foo=doc->'$.field'
OracleConfidenNal–Restricted 11
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQL5.7:JSONSupport(cont.)• Plus…• Generated/VirtualColumns– IndexJSONdata– ForeignkeystoJSONdata– SQLviewsforJSONdata
OracleConfidenNal–Restricted 12
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalDatabases,DocumentDatabasesandMySQL
MySQLJSONSupport
DocumentUseCases
TheXDevAPI
Ge\ngitallworkingtogether
13
1
2
3
4
5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
ExtracNngJSONfromaRelaNonalDBRela+onalIn,Rela+onal+DocumentOut
• DatastoredinrelaNonaltables,butfrontendusesJSON• JSONdirectlymapstonaNvedatastructuresinmanylanguages– OveneasierforapplicaNoncodetouse– JavaScript,Python,Rubyetc– InbrowserJavaScript
OracleConfidenNal–Restricted 14
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
ExtracNngJSONfromaRelaNonalDBRela+onalIn,Rela+onal+DocumentOut
• SQLFuncNonstoconstructJSON– JSON_OBJECT(),JSON_ARRAY()
• Ex.:SELECT JSON_OBJECT('cust_id', id, 'name', name, 'email', email) FROM customer;
CREATE VIEW customer_json AS
SELECT JSON_OBJECT('cust_id', id, 'name', name, 'email', email) as doc FROM customer;
SELECT * FROM customer_json;
• UpdatesandinsertssNllhappenthroughthetablecolumns
OracleConfidenNal–Restricted 15
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
UsingMySQLasaJSONDocumentContainerDocumentIn,Rela+onal+DocumentOut
• VirtuallySchemaless– Unstructureddata– Noclear,fixedstructureforthedata…recordscanhavedifferentfields– Ovendatathatisnotinvolvedinbusinessrules– Examples:"product_info","properNes","opNons"etc
• DatadoesnotmapcleanlyintoarelaNonalmodel(arrays,hierarchicaldataetc)• Prototyping
OracleConfidenNal–Restricted 16
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQLasaJSONDocumentContainer
OracleConfidenNal–Restricted 17
Example:"properNes"table
hgps://www.mediawiki.org/wiki/Manual:Database_layout
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQLasaJSONDocumentContainer
OracleConfidenNal–Restricted 18
Example:"product_info"tableproduct_id a<ribute value
9 size M
9 color red
9 fabric cogon
11 flavour strawberry
12 capacity 128GB
12 speedclass class10
13 connecNvity Wi-Fi
13 storage 64GB
13 screensize 8.9"
13 resoluNon 2560x1600(339ppi)
13 bagerylife 12hours
{"product_id":9,"size":"M","color":"red","fabric":"cogon"},{"product_id":11,"flavour":"strawberry"},{"product_id":12,"capacity":"128GB","speedclass":"class10"},{
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQLasaJSONDocumentContainerDocumentIn,Rela+onal+DocumentOut
• AnordinaryMySQLtablewithasingleJSONdatacolumn• GeneratedcolumnsallowSQLenginetolookinsidetheJSONdata– Virtualcolumns– PrimaryKeys– Indexes– ForeignKeys
• WritesontheJSONcolumn• ReadsprimarilyfromtheJSONcolumns
OracleConfidenNal–Restricted 19
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
HybridRelaNonalandJSONRela+onal+DocumentIn,Rela+onal+DocumentOut
• DatabaseismostlyrelaNonal• SomepartsofthedatabaseareunstructuredordoesnotmodelcleanlyasrelaNonal• JSONcolumnsinrelaNonaltables• QueriescanmixandmatchJSONandcolumndata• EvoluNonpathforDocumentbasedapplicaNons
OracleConfidenNal–Restricted 20
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
HybridRelaNonalandJSONRela+onal+DocumentIn,Rela+onal+DocumentOut
product (product_id, name, category_id, …);
product_info (product_id, attribute, value);
OracleConfidenNal–Restricted 21
product (product_id, name, category_id, …, attributes JSON);
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalDatabases,DocumentDatabasesandMySQL
MySQLJSONSupport
DocumentUseCases
TheXDevAPI
Ge\ngitallworkingtogether
1
2
3
4
22
5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
DocumentOperaNonsviaSQL• Powerful• Allowscomplexqueries• But…sNlldifficulttouse
OracleConfidenNal–Restricted 23
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
DocumentOperaNonsviaSQL
CREATE TABLE product (
id VARCHAR(32) GENERATED ALWAYS AS (JSON_EXTRACT(doc, '$.id')) STORED,
doc JSON
);
INSERT INTO product VALUES (1, '{…}');
SELECT * FROM product WHERE JSON_EXTRACT(doc, '$.field') = value;
etc.
OracleConfidenNal–Restricted 24
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
TheXDevAPI• AbstracNonoverSQL• Focusedon4basicCRUDoperaNons(Create,Read,Update,Delete)• Fluent,NaNveLanguageAPI• NoknowledgeofSQLneeded• XProtocol– CRUDrequestsencodedatprotocollevel– Requestdetails"visible"(vs"opaque"SQLstrings)
OracleConfidenNal–Restricted 25
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
CollecNonandSchemaOperaNons• GetahandletoaSchemamydb = session.getSchema("mydb");
• CreateaCollecNonmydb.createCollection("products");
• Geta(local)referencetoaCollecNonproducts = mydb.getCollection("products");
OracleConfidenNal–Restricted 26
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
AddDocument
products.add({"name":"bananas", "color":"yellow"}).execute();
OracleConfidenNal–Restricted 27
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
FindDocuments
OracleConfidenNal–Restricted 28
products.find("color = 'yellow'").sort(["name"]).execute();
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
ModifyDocuments
OracleConfidenNal–Restricted 29
products.modify("product_id = 123").set("color", "red").execute();
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RemoveDocuments
OracleConfidenNal–Restricted 30
products.remove("product_id = 123").execute();
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
XDevAPISessions• XSession– Stateless– CRUDonly,noSQL– AbstractstheconnecNon
• NodeSession– DirectconnecNontoadatabasenode– AllowsCRUDandSQL
OracleConfidenNal–Restricted 31
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
OtherOperaNonsonCollecNons• CreateanIndexdb.post.createIndex("email").field("author.email","text(30)",false)
OracleConfidenNal–Restricted 32
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
CRUDOperaNons–NoSQL/DocumentandSQL/RelaNonal
Opera+on Document Rela+onalCreate CollecNon.add() Table.insert()Read CollecNon.find() Table.select()Update CollecNon.modify() Table.update()Delete CollecNon.remove() Table.delete()
33
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
RelaNonalDatabases,DocumentDatabasesandMySQL
MySQLJSONSupport
DocumentUseCases
TheXDevAPI
Ge\ngitallworkingtogether
1
2
3
4
34
5
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
5.7.12DevelopmentPreviewRelease• MySQL5.7.12withDocumentStoreplugin• MySQLShell1.0.3• Connector/J7.0• Connector/Net7.0• Connector/Node.js1.0
OracleConfidenNal–Restricted 35
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQL5.7,Connectors,Drivers,andProtocols
36
MySQL
Plugins
XProtocolPlugin MemcachedPluginCore
MySQLConnectorsandDrivers
XProtocolStdProtocol
Memcacheddriver
XProtocol33060
StdProtocol3306
SQLAPI CRUDandSQLAPIs
MemcacheProtocol
XandStdProtocols
MySQLShell
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
XDevAPIConnectors–MySQLConnector/Java7.0uri = "mysql:x://localhost:33060/test?user=user&password=mypwd"'; !
XSession session = new MysqlxSessionFactory().getSession(uri); !
Schema schema = session.getDefaultSchema();!
// document walkthrough!
Collection coll = schema.createCollection("myBooks", true); !
DbDoc newDoc = new DbDoc().add("isbn", !new JsonString().setValue("12345")); !
newDoc.add("title", !new JsonString().setValue("Effi Briest")); !
newDoc.add("author", !new JsonString().setValue("Theodor Fontane")); !
newDoc.add("currentlyReadingPage", !new JsonNumber().setValue(String.valueOf(42))); !
coll.add(newDoc).execute(); !
DocResult docs = coll.find("title = 'Effi Briest' and currentlyReadingPage > 10").execute(); !
DbDoc book = docs.fetchOne(); !
System.err.println("Currently reading "! + ((JsonString)book.get("title")).getString() ! + " on page " ! + ((JsonNumber)book.get("currentlyReadingPage")).getInteger()); !
!
// increment the page number and fetch it again!
coll.modify("isbn = 12345"). ! set("currentlyReadingPage", ! ((JsonNumber)book.get("currentlyReadingPage")).getInteger() + 1).execute(); !
docs = coll.find("title = 'Effi Briest' and currentlyReadingPage > 10").execute(); !
book = docs.fetchOne(); !
System.err.println("Currently reading " ! + ((JsonString)book.get("title")).getString() ! + " on page "! + ((JsonNumber)book.get("currentlyReadingPage")).getInteger()); !
OracleConfidenNal–Restricted 37
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
XDevAPIConnectors–MySQLConnector/Net7.0using(XSessionsession=
MySQLX.GetSession("mysqlx://test:test@localhost:33060")){stringschemaName="test";SchematestSchema=session.GetSchema(schemaName);if(testSchema.ExistsInDatabase())session.DropSchema(schemaName);session.CreateSchema(schemaName);//insertsomedocsCollectioncoll=testSchema.CreateCollection("myDocs");vardocs=new[]{new{_id=1,title="Book1",pages=20},new{_id=2,title="Book2",pages=30},new{_id=3,title="Book3",pages=40},new{_id=4,title="Book4",pages=50},};
Resultr=coll.Add(docs).Execute();Console.WriteLine("Docsadded:"+r.RecordsAffected);//modifysomevaluesr=coll.Modify("_id=:ID").
Bind("Id",2).Set("pages","25").Execute();Console.WriteLine("Docsmodified:"+r.RecordsAffected);//removeabookr=coll.Remove("_id=:ID").Bind("Id",4).Execute();Console.WriteLine("Docsremoved:"+r.RecordsAffected);//listtheresultsvarresult30orMore=coll.Find("pages>20").
OrderBy("pagesDESC").Execute().FetchAll();foreach(vardocinresult30orMore){Console.WriteLine(doc.ToString());}}
OracleConfidenNal–Restricted 38
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
XDevAPIConnectors–MySQLConnector/Node.js1.0NEW!const mysqlx = require('mysqlx'); !!mysqlx.getSession({ ! host: 'localhost', ! dbUser: 'myuser', ! dbPassword: 'secret' !}).then(session => { ! const collection = session.getSchema('myschema').getCollection('mycollection'); ! return Promise.all([ ! collection.add({ foo: "bar", something: { nested: [1,2,3,4] } }).execute(); ! session.close(); ! ]) !}).catch(err => { ! console.log(err); !}); !!
!const collection = session.getSchema('myschema').getCollection('questions'); !collection.find("answer == 42") ! .orderBy("foo DESC") ! .limit(10) ! .execute(doc => console.log(doc)) // print the document received, callback called for each doc! .then(() => console.log("All done") // Promise resolves when all data is there! .catch((err) => console.log("Oups, an error", err); ! !
OracleConfidenNal–Restricted 39
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQLShell
OracleConfidenNal–Restricted 40
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
MySQLPluginforVisualStudio
OracleConfidenNal–Restricted 41
Copyright©2016Oracleand/oritsaffiliates.Allrightsreserved.|
ResourcesTopic Link(s)
MySQLasaDocumentDatabase hgp://dev.mysql.com/doc/refman/5.7/en/document-database.html
MySQLShell hgp://dev.mysql.com/doc/refman/5.7/en/mysql-shell.htmlhgp://dev.mysql.com/doc/refman/5.7/en/mysqlx-shell-tutorial-javascript.htmlhgp://dev.mysql.com/doc/refman/5.7/en/mysqlx-shell-tutorial-python.html
XDevAPI hgp://dev.mysql.com/doc/x-devapi-userguide/en/
XPlugin hgp://dev.mysql.com/doc/refman/5.7/en/x-plugin.html
MySQLJSON hgp://mysqlserverteam.com/tag/json/hgps://dev.mysql.com/doc/refman/5.7/en/json.htmlhgps://dev.mysql.com/doc/refman/5.7/en/json-funcNons.html
Blogs hgp://mysqlserverteam.com/category/docstore/
42