PHP & MySQL -- How do PDO, MySQLi, and X DevAPI Do What They Do Dave Stokes @stoker David.Stokes @Oracle.com MySQL Community Manager MySQL Community Team Slides available at slideshare.net/davestokes Copyright © 2021 Oracle and/or its affiliates.
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, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2019 Oracle and/or its affiliates.
Overview of the MySQL PHP drivers/connectors/API ¶ There are several PHP APIs for accessing the MySQL database. Users can choose between mysqli, PDO_MySQL, or X DevAPI All three use mysqlnd driver
Overview of the MySQL PHP drivers/connectors/API ¶ There are several PHP APIs for accessing the MySQL database. Users can choose between the mysqli, PDO_MySQL, or X DevAPI extensions. All three use mysqlnd driver → drop-in replacement for the MySQL Client Library
The mysqlnd library is highly optimized for and tightly integrated into PHP. The MySQL Client Library cannot offer the same optimizations because it is a general-purpose client library. The mysqlnd library is using PHP internal C infrastructure for seamless integration into PHP. In addition, it is using PHP memory management, PHP Streams (I/O abstraction) and PHP string handling routines. The use of PHP memory management by mysqlnd allows, for example, memory savings by using read-only variables (copy on write) and makes mysqlnd apply to PHP memory limits. Additional advantages include: ● Powerful plugin API to extend feature set ● Asynchronous, non-blocking queries ● 150+ performance statistics ● Ships together with the PHP 5.3, and later, source ● No need to install MySQL Client Library ● Powerful plugins. See Below.
Why this talk came about No three way comparisons Examples lacking Lots of old information Truth versus mythology
PDO PDO_MYSQL is a driver that implements the PHP Data Objects (PDO) interface to enable access from PHP to MySQL databases (and several other RDMS). PDO_MYSQL uses emulated prepared statements by default. Supported Databases ● CURBID ● SQL Server ● Firebird ● DB2 ● Informix ● MySQL ● SQL Server/Sybase ● Oracle ● PostgreSQL ● SQLite ● ODBC/DB2
MySQLi The mysqli extension allows you to access the functionality provided by MySQL 4.1 and above. No client side prepared statements.
X DevAPI The X DevAPI is a common API provided by multiple MySQL Connectors providing easy access to relational tables as well as collections of JSON documents. The X DevAPI uses the X Protocol, the new generation client-server protocol of the MySQL 8.0 server. NOT AN ORM!!
The old mysql connector End of Life was with PHP 5.5 (2016) Still a lot of code out there to be ported DO NOT USE!!! Use mysqli
Somethings are going to be similar for all three After all you are connecting to the same database So things like authentication will be the same hostname username password port schema/database extra
// mysqli $mysqli = new mysqli("example.com", "user", "password", "database"); $result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $result->fetch_assoc(); // PDO $pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password'); $statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $statement->fetch(PDO::FETCH_ASSOC); // X DevAPI $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060"); $collection = $schema->getCollection("stuff"); var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
// mysqli $mysqli = new mysqli("example.com", "user", "password", "database"); $result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $result->fetch_assoc(); // PDO $pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password'); $statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $statement->fetch(PDO::FETCH_ASSOC); // X DevAPI $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060"); $collection = $schema->getCollection("stuff"); var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
Test Data https://dev.mysql.com/doc/index-other.html world, world_x, and sakila datasets
Please keep your data safe! Copyright © 2019 Oracle and/or its affiliates.
SSL/TLS MySQL 8.0 is designed to be secure by default and will generate certificates for you (if you do not want to use your own).
PHP & MySQL -- Things in common ● Open Source ● LAMP Stack ● Extremely Popular ● ‘Backbone’ tech for the internet ● ~25 years old ● Predicted to be dead for ~24.5 years ● Sexy developers!
Login to MySQL Instance Specify • host • user • password (please use good ones) • schema (optional)
mysqli <?php $servername = "localhost"; $username = "root"; $password = "hidave"; // Create connection $conn = new mysqli($servername, $username, $password, "sakila" ); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } echo "Connected successfully*<br>"; ?>
PDO <?php $servername = "localhost"; $username = "demo"; $password = "Passw0rd!"; try { $conn = new PDO("mysql:host=$servername;dbname=world", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } ?>
X DevAPI <<?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } ?>
Accessing your data Again this stuff is pretty similar
mysqli <?php $servername = "localhost"; $username = "root"; $password = "hidave"; // Create connection $conn = new mysqli($servername, $username, $password, "world" ); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $result = $conn->query("SELECT * FROM country WHERE Code='USA'"); while ($row = $result->fetch_row()) { printf("%s (%s)n", $row[0], $row[1]); }
pdo <?php $servername = "localhost"; $username = "dave"; $password = "Passw0rd!"; try { $conn = new PDO("mysql:host=$servername;dbname=world", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } foreach($conn->query("SELECT * FROM country WHERE Code = 'USA'") as $row) { printf("%s (%s)n", $row[0], $row[1] ); }
X DevAPI JSON <?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world_x"); $collection = $schema->getCollection("countryinfo"); print_r($collection->find("Code = 'USA'") ->fields("[Code,Name]") ->execute() ->fetchOne());
X DevAPI table <?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code') ->where("Code = 'USA'") ->execute() ->fetchALL(); print_r($row);
X DevAPI table <?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code') ->where("Code = 'USA'") ->execute() ->fetchALL(); print_r($row); Not SQL!!
Document Store vs. Relational Tables Document Store $schema = $session->getSchema("world_x"); $collection = $schema->getCollection("countryinfo"); print_r($collection->find("Code = 'USA'")->fields("[Code,Name]")->execute()->fetchOne()); Relational Table $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code')->where("Code = 'USA'")->execute()->fetchALL(); print_r($row);
X DevAPI SQL function <?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/world_x"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $rows = $session->sql("SELECT * FROM country LIMIT 2")->execute()->fetchAll(); print_r($rows);
Parameters & Prepared Statements PDO allows positional and named parameters mysqli uses positional ? placeholder X DevAPI uses named bindings
A prepared statement is a feature used to execute the same SQL statements repeatedly with high efficiency. 1. An SQL statement template is created and sent to the database with certain parameters marked as reserved ‘place holders’ 2. The database syntax checks and performs query optimization on the SQL statement template, storing the result without executing it 3. Sometime later the application binds the values to the parameter and the database executes the statement. The application may execute the statement as many times as it wants with different values
Main advantages of prepared statements • Query plan is only generated once -- big savings in optimization • Sending only the parameters saves bandwidth over sending the entire query. • Useful in reducing SQL injections! The parameter values are transmitted using a binary protocol and bound parameters do not need to be escaped as they are never substituted into the query string directly. If the original statement template is not derived from external input, SQL injection cannot occur. So no ‘Little Bobby Drop Tables’
Main disadvantage of prepared statements • For a simple one-off query you need an extra round trip to send statement and
MySQL 8.0 provides support for server-side prepared statements This support takes advantage of the efficient client/server binary protocol. • Less overhead for parsing the statement each time it is executed. Typically, database applications process large volumes of almost-identical statements, with only changes to literal or variable values in clauses such as WHERE for queries and deletes, SET for updates, and VALUES for inserts. • Protection against SQL injection attacks. The parameter values can contain unescaped SQL quote and delimiter characters.
Example in SQL mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1;
mysqli $a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute();
$a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Placeholder for auto_incremented column
mysqli $a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Data Types
mysqli $a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Data Types Character Description i Integer d Double s String b Blob
mysqli $a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); $a $b $c
m03.php $a = 72; $b = 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); $a $b $c INSERT INTO x (id,a,b,c) VALUES (NULL,72,4,”Testing”)
pdo $a = 33; $b = 101; $c = "Whohoo!"; $conn=->setAttributes(PDO::ATTR_EMULATE_PREPARES,false); $stmt = $conn->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL, :a, :b, :c)"); $stmt->execute([':a' => $a, ':b' => $b, ':c' => $c]);
pdo $a = 33; $b = 101; $c = "Whohoo!"; $conn=->setAttributes(PDO::ATTR_EMULATE_PREPARES,false); $stmt = $conn->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL, :a, :b, :c)"); $stmt->execute([':a' => $a, ':b' => $b, ':c' => $c]); This says to use prepared statements not emulated prepared statements!
Emulated prepared statements - PDO Default PDO doesn’t send the SQL string to the server during prepare(). ● The SQL string is on the client-side, in memory in PDO code. ● The SQL query for is not checked for syntax or other errors! When execute() runs the query that was saved as an emulated-prepared query performs string-replacement on the saved SQL string before it submits the final SQL string to the server. ● This is the first time the server has seen that query so the query must be have the syntax checked and the passed to query optimizer.
xdevapi $collection->find("Code = :code") ->fields("[Code,Name]") ->bind(['code' => 'USA']) ->execute() ->fetchOne();
MySQL 8.0 provides support for server-side prepared statements. ALTER TABLE ALTER USER ANALYZE TABLE CACHE INDEX CALL CHANGE MASTER CHECKSUM {TABLE | TABLES} COMMIT {CREATE | DROP} INDEX {CREATE | RENAME | DROP} DATABASE {CREATE | DROP} TABLE {CREATE | RENAME | DROP} USER {CREATE | DROP} VIEW DELETE DO FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | USER_RESOURCES} GRANT INSERT INSTALL PLUGIN KILL LOAD INDEX INTO CACHE OPTIMIZE TABLE RENAME TABLE REPAIR TABLE REPLACE RESET {MASTER | SLAVE} REVOKE SELECT SET SHOW BINLOG EVENTS SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} SHOW {MASTER | BINARY} LOGS SHOW {MASTER | SLAVE} STATUS SLAVE {START | STOP} TRUNCATE TABLE UNINSTALL PLUGIN UPDATE
Buffering Queries are buffered by default. Query results are stored in memory, which allows additional operations like counting the number of rows or seeking the current result pointer.
mysqli -- unbuffered m04.php $result = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
PDO -- unbuffered p04.php $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
So which one do you choose?
'comparisons are odorous' - Shakespeare’s Much Ado About Nothing So you would think that comparing three connectors would be comparing ‘apples to apples’. Nope
CREATE TABLE x (id SERIAL PRIMARY KEY NOT NULL, a INT UNSIGNED NOT NULL, b INT UNSIGNED NOT NULL, c INT UNSIGNED NOT NULL); #!/usr/bin/python import random print("SET AUTOCOMMIT=0;"); for i in range(10): print(‘BEGIN TRANSACTION;’) for j in range(1000): a = random.randint(1,1000000000) b = random.randint(1,10000000) c = random.randint(1,1000000) s = 'INSERT INTO x VALUES (NULL,' + repr(a) + ', ' + repr(b) + ', ' + repr(c) + ');' print(s) print(“COMMIT;”) Schema Script to generate rows
for ($x=0; $x < 1000000 ; $x++) { $y=rand(1,10000); $result= = $conn->query(“SELECT * FROM x WHERE id=$y;”); } m06-mt.php real 1m11.647s user 0m5.911s sys 0m8.310s p06-mt.php real 1m9.242s user 0m8.578s sys 0m7.987s x06x-mt.php real 3m5.109s user 1m42.753s sys 0m27.542s select(‘*’) ->where(“id = :id”) ->bind([‘id’ => $y]) ->execute()-fetchone(); Averages of 10 runs, high/low tossed out
And then I changed Hardware... And yup, the numbers skewed differently and testing multiple threads, bigger datasets, and other approaches muddled things further. PDO was usually just slightly faster than mysqli, just a smidge. Benchmark your environment
Who supports the code? mysqli Oracle engineers X DevAPI Oracle engineers PDO Oracle engineers* * with reservations
Conclusion Use X DevAPI if you do not like SQL or are using the MySQL Document Store NoSQL database. PDO does support multiple databases which is a plus if you really can support using another data & can port. mysqli can handle asynchronous calls, mysql->info().
Follow us on Social Media Copyright © 2020, Oracle and/or its affiliates 58 MySQLCommunity.slack.com
Copyright © 2020, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 59 Get $300 in credits and try MySQL Database Service free for 30 days. https://www.oracle.com/cloud/free/ Test Drive MySQL Database Service For Free Today
Startups get cloud credits and a 70% discount for 2 years, global exposure via marketing, events, digital promotion, and media, plus access to mentorship, capital and Oracle’s 430,000+ customers Customers meet vetted startups in transformative spaces that help them stay ahead of their competition Oracle stays at the competitive edge of innovation with solutions that complement its technology stack We have saved around 40% of our costs and are able to reinvest that back into the business. And we are scaling across EMEA, and that’s basically all because of Oracle.” —Asser Smidt CEO and Cofounder, BotSupply Oracle for Startups - enroll at oracle.com/startup A Virtuous Cycle of Innovation, Everybody Wins. Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 60
Then please consider buying my book on the JSON data type, how to use the supporting functions, and it is filled with example code to get you up to speed! Interested in using JSON with MySQL? Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 61
Thank You Dave Stokes MySQL Community Team david.stokes @ Oracle.com @stoker slideshare.net/davestokes Copyright © 2021 Oracle and/or its affiliates.
The preceding 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, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2021 Oracle and/or its affiliates.

Php &amp; my sql - how do pdo, mysq-li, and x devapi do what they do

  • 1.
    PHP & MySQL-- How do PDO, MySQLi, and X DevAPI Do What They Do Dave Stokes @stoker David.Stokes @Oracle.com MySQL Community Manager MySQL Community Team Slides available at slideshare.net/davestokes Copyright © 2021 Oracle and/or its affiliates.
  • 2.
    The following isintended 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, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2019 Oracle and/or its affiliates.
  • 3.
    Overview of theMySQL PHP drivers/connectors/API ¶ There are several PHP APIs for accessing the MySQL database. Users can choose between mysqli, PDO_MySQL, or X DevAPI All three use mysqlnd driver
  • 4.
    Overview of theMySQL PHP drivers/connectors/API ¶ There are several PHP APIs for accessing the MySQL database. Users can choose between the mysqli, PDO_MySQL, or X DevAPI extensions. All three use mysqlnd driver → drop-in replacement for the MySQL Client Library
  • 5.
    The mysqlnd libraryis highly optimized for and tightly integrated into PHP. The MySQL Client Library cannot offer the same optimizations because it is a general-purpose client library. The mysqlnd library is using PHP internal C infrastructure for seamless integration into PHP. In addition, it is using PHP memory management, PHP Streams (I/O abstraction) and PHP string handling routines. The use of PHP memory management by mysqlnd allows, for example, memory savings by using read-only variables (copy on write) and makes mysqlnd apply to PHP memory limits. Additional advantages include: ● Powerful plugin API to extend feature set ● Asynchronous, non-blocking queries ● 150+ performance statistics ● Ships together with the PHP 5.3, and later, source ● No need to install MySQL Client Library ● Powerful plugins. See Below.
  • 6.
    Why this talkcame about No three way comparisons Examples lacking Lots of old information Truth versus mythology
  • 7.
    PDO PDO_MYSQL is adriver that implements the PHP Data Objects (PDO) interface to enable access from PHP to MySQL databases (and several other RDMS). PDO_MYSQL uses emulated prepared statements by default. Supported Databases ● CURBID ● SQL Server ● Firebird ● DB2 ● Informix ● MySQL ● SQL Server/Sybase ● Oracle ● PostgreSQL ● SQLite ● ODBC/DB2
  • 8.
    MySQLi The mysqli extensionallows you to access the functionality provided by MySQL 4.1 and above. No client side prepared statements.
  • 9.
    X DevAPI The XDevAPI is a common API provided by multiple MySQL Connectors providing easy access to relational tables as well as collections of JSON documents. The X DevAPI uses the X Protocol, the new generation client-server protocol of the MySQL 8.0 server. NOT AN ORM!!
  • 11.
    The old mysqlconnector End of Life was with PHP 5.5 (2016) Still a lot of code out there to be ported DO NOT USE!!! Use mysqli
  • 12.
    Somethings are goingto be similar for all three After all you are connecting to the same database So things like authentication will be the same hostname username password port schema/database extra
  • 13.
    // mysqli $mysqli =new mysqli("example.com", "user", "password", "database"); $result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $result->fetch_assoc(); // PDO $pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password'); $statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $statement->fetch(PDO::FETCH_ASSOC); // X DevAPI $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060"); $collection = $schema->getCollection("stuff"); var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
  • 14.
    // mysqli $mysqli =new mysqli("example.com", "user", "password", "database"); $result = $mysqli->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $result->fetch_assoc(); // PDO $pdo = new PDO('mysql:host=example.com;dbname=database', 'user', 'password'); $statement = $pdo->query("SELECT 'Hello, dear MySQL user!' AS _message"); $row = $statement->fetch(PDO::FETCH_ASSOC); // X DevAPI $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/p1:33060"); $collection = $schema->getCollection("stuff"); var_dump($collection->find("name = 'Dave'")->execute()->fetchOne());
  • 15.
  • 16.
    Please keep yourdata safe! Copyright © 2019 Oracle and/or its affiliates.
  • 17.
    SSL/TLS MySQL 8.0 isdesigned to be secure by default and will generate certificates for you (if you do not want to use your own).
  • 18.
    PHP & MySQL-- Things in common ● Open Source ● LAMP Stack ● Extremely Popular ● ‘Backbone’ tech for the internet ● ~25 years old ● Predicted to be dead for ~24.5 years ● Sexy developers!
  • 19.
    Login to MySQLInstance Specify • host • user • password (please use good ones) • schema (optional)
  • 20.
    mysqli <?php $servername = "localhost"; $username= "root"; $password = "hidave"; // Create connection $conn = new mysqli($servername, $username, $password, "sakila" ); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } echo "Connected successfully*<br>"; ?>
  • 21.
    PDO <?php $servername = "localhost"; $username= "demo"; $password = "Passw0rd!"; try { $conn = new PDO("mysql:host=$servername;dbname=world", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } ?>
  • 22.
    X DevAPI <<?PHP try { $session= mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } ?>
  • 23.
    Accessing your data Againthis stuff is pretty similar
  • 24.
    mysqli <?php $servername = "localhost"; $username= "root"; $password = "hidave"; // Create connection $conn = new mysqli($servername, $username, $password, "world" ); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $result = $conn->query("SELECT * FROM country WHERE Code='USA'"); while ($row = $result->fetch_row()) { printf("%s (%s)n", $row[0], $row[1]); }
  • 25.
    pdo <?php $servername = "localhost"; $username= "dave"; $password = "Passw0rd!"; try { $conn = new PDO("mysql:host=$servername;dbname=world", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } foreach($conn->query("SELECT * FROM country WHERE Code = 'USA'") as $row) { printf("%s (%s)n", $row[0], $row[1] ); }
  • 26.
    X DevAPI JSON <?PHP try{ $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world_x"); $collection = $schema->getCollection("countryinfo"); print_r($collection->find("Code = 'USA'") ->fields("[Code,Name]") ->execute() ->fetchOne());
  • 27.
    X DevAPI table <?PHP try{ $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code') ->where("Code = 'USA'") ->execute() ->fetchALL(); print_r($row);
  • 28.
    X DevAPI table <?PHP try{ $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code') ->where("Code = 'USA'") ->execute() ->fetchALL(); print_r($row); Not SQL!!
  • 29.
    Document Store vs.Relational Tables Document Store $schema = $session->getSchema("world_x"); $collection = $schema->getCollection("countryinfo"); print_r($collection->find("Code = 'USA'")->fields("[Code,Name]")->execute()->fetchOne()); Relational Table $schema = $session->getSchema("world"); $table = $schema->getTable("country"); $row = $table->select('Name','Code')->where("Code = 'USA'")->execute()->fetchALL(); print_r($row);
  • 30.
    X DevAPI SQLfunction <?PHP try { $session = mysql_xdevapigetSession("mysqlx://root:hidave@localhost/world_x"); } catch (Exception $e) { die("Connection could not be established: " / $e->getMessage()); } $rows = $session->sql("SELECT * FROM country LIMIT 2")->execute()->fetchAll(); print_r($rows);
  • 31.
    Parameters & PreparedStatements PDO allows positional and named parameters mysqli uses positional ? placeholder X DevAPI uses named bindings
  • 32.
    A prepared statementis a feature used to execute the same SQL statements repeatedly with high efficiency. 1. An SQL statement template is created and sent to the database with certain parameters marked as reserved ‘place holders’ 2. The database syntax checks and performs query optimization on the SQL statement template, storing the result without executing it 3. Sometime later the application binds the values to the parameter and the database executes the statement. The application may execute the statement as many times as it wants with different values
  • 33.
    Main advantages ofprepared statements • Query plan is only generated once -- big savings in optimization • Sending only the parameters saves bandwidth over sending the entire query. • Useful in reducing SQL injections! The parameter values are transmitted using a binary protocol and bound parameters do not need to be escaped as they are never substituted into the query string directly. If the original statement template is not derived from external input, SQL injection cannot occur. So no ‘Little Bobby Drop Tables’
  • 34.
    Main disadvantage ofprepared statements • For a simple one-off query you need an extra round trip to send statement and
  • 35.
    MySQL 8.0 providessupport for server-side prepared statements This support takes advantage of the efficient client/server binary protocol. • Less overhead for parsing the statement each time it is executed. Typically, database applications process large volumes of almost-identical statements, with only changes to literal or variable values in clauses such as WHERE for queries and deletes, SET for updates, and VALUES for inserts. • Protection against SQL injection attacks. The parameter values can contain unescaped SQL quote and delimiter characters.
  • 36.
    Example in SQL mysql>PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1;
  • 37.
    mysqli $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute();
  • 38.
    $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Placeholder for auto_incremented column
  • 39.
    mysqli $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Data Types
  • 40.
    mysqli $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); Data Types Character Description i Integer d Double s String b Blob
  • 41.
    mysqli $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); $a $b $c
  • 42.
    m03.php $a = 72; $b= 4; $c = "Testing"; $stmt = $mysqli->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL,?,?,?);"); $stmt->bind_param("iis",$a, $b, $c); $stmt->execute(); $a $b $c INSERT INTO x (id,a,b,c) VALUES (NULL,72,4,”Testing”)
  • 43.
    pdo $a = 33; $b= 101; $c = "Whohoo!"; $conn=->setAttributes(PDO::ATTR_EMULATE_PREPARES,false); $stmt = $conn->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL, :a, :b, :c)"); $stmt->execute([':a' => $a, ':b' => $b, ':c' => $c]);
  • 44.
    pdo $a = 33; $b= 101; $c = "Whohoo!"; $conn=->setAttributes(PDO::ATTR_EMULATE_PREPARES,false); $stmt = $conn->prepare("INSERT INTO x (id,a,b,c) VALUES (NULL, :a, :b, :c)"); $stmt->execute([':a' => $a, ':b' => $b, ':c' => $c]); This says to use prepared statements not emulated prepared statements!
  • 45.
    Emulated prepared statements- PDO Default PDO doesn’t send the SQL string to the server during prepare(). ● The SQL string is on the client-side, in memory in PDO code. ● The SQL query for is not checked for syntax or other errors! When execute() runs the query that was saved as an emulated-prepared query performs string-replacement on the saved SQL string before it submits the final SQL string to the server. ● This is the first time the server has seen that query so the query must be have the syntax checked and the passed to query optimizer.
  • 46.
  • 47.
    MySQL 8.0 providessupport for server-side prepared statements. ALTER TABLE ALTER USER ANALYZE TABLE CACHE INDEX CALL CHANGE MASTER CHECKSUM {TABLE | TABLES} COMMIT {CREATE | DROP} INDEX {CREATE | RENAME | DROP} DATABASE {CREATE | DROP} TABLE {CREATE | RENAME | DROP} USER {CREATE | DROP} VIEW DELETE DO FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | USER_RESOURCES} GRANT INSERT INSTALL PLUGIN KILL LOAD INDEX INTO CACHE OPTIMIZE TABLE RENAME TABLE REPAIR TABLE REPLACE RESET {MASTER | SLAVE} REVOKE SELECT SET SHOW BINLOG EVENTS SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW} SHOW {MASTER | BINARY} LOGS SHOW {MASTER | SLAVE} STATUS SLAVE {START | STOP} TRUNCATE TABLE UNINSTALL PLUGIN UPDATE
  • 48.
    Buffering Queries are bufferedby default. Query results are stored in memory, which allows additional operations like counting the number of rows or seeking the current result pointer.
  • 49.
    mysqli -- unbufferedm04.php $result = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
  • 50.
    PDO -- unbufferedp04.php $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
  • 51.
    So which onedo you choose?
  • 52.
    'comparisons are odorous'- Shakespeare’s Much Ado About Nothing So you would think that comparing three connectors would be comparing ‘apples to apples’. Nope
  • 53.
    CREATE TABLE x(id SERIAL PRIMARY KEY NOT NULL, a INT UNSIGNED NOT NULL, b INT UNSIGNED NOT NULL, c INT UNSIGNED NOT NULL); #!/usr/bin/python import random print("SET AUTOCOMMIT=0;"); for i in range(10): print(‘BEGIN TRANSACTION;’) for j in range(1000): a = random.randint(1,1000000000) b = random.randint(1,10000000) c = random.randint(1,1000000) s = 'INSERT INTO x VALUES (NULL,' + repr(a) + ', ' + repr(b) + ', ' + repr(c) + ');' print(s) print(“COMMIT;”) Schema Script to generate rows
  • 54.
    for ($x=0; $x< 1000000 ; $x++) { $y=rand(1,10000); $result= = $conn->query(“SELECT * FROM x WHERE id=$y;”); } m06-mt.php real 1m11.647s user 0m5.911s sys 0m8.310s p06-mt.php real 1m9.242s user 0m8.578s sys 0m7.987s x06x-mt.php real 3m5.109s user 1m42.753s sys 0m27.542s select(‘*’) ->where(“id = :id”) ->bind([‘id’ => $y]) ->execute()-fetchone(); Averages of 10 runs, high/low tossed out
  • 55.
    And then Ichanged Hardware... And yup, the numbers skewed differently and testing multiple threads, bigger datasets, and other approaches muddled things further. PDO was usually just slightly faster than mysqli, just a smidge. Benchmark your environment
  • 56.
    Who supports thecode? mysqli Oracle engineers X DevAPI Oracle engineers PDO Oracle engineers* * with reservations
  • 57.
    Conclusion Use X DevAPIif you do not like SQL or are using the MySQL Document Store NoSQL database. PDO does support multiple databases which is a plus if you really can support using another data & can port. mysqli can handle asynchronous calls, mysql->info().
  • 58.
    Follow us onSocial Media Copyright © 2020, Oracle and/or its affiliates 58 MySQLCommunity.slack.com
  • 59.
    Copyright © 2020,Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 59 Get $300 in credits and try MySQL Database Service free for 30 days. https://www.oracle.com/cloud/free/ Test Drive MySQL Database Service For Free Today
  • 60.
    Startups get cloudcredits and a 70% discount for 2 years, global exposure via marketing, events, digital promotion, and media, plus access to mentorship, capital and Oracle’s 430,000+ customers Customers meet vetted startups in transformative spaces that help them stay ahead of their competition Oracle stays at the competitive edge of innovation with solutions that complement its technology stack We have saved around 40% of our costs and are able to reinvest that back into the business. And we are scaling across EMEA, and that’s basically all because of Oracle.” —Asser Smidt CEO and Cofounder, BotSupply Oracle for Startups - enroll at oracle.com/startup A Virtuous Cycle of Innovation, Everybody Wins. Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 60
  • 61.
    Then please consider buyingmy book on the JSON data type, how to use the supporting functions, and it is filled with example code to get you up to speed! Interested in using JSON with MySQL? Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 61
  • 62.
    Thank You Dave Stokes MySQLCommunity Team david.stokes @ Oracle.com @stoker slideshare.net/davestokes Copyright © 2021 Oracle and/or its affiliates.
  • 63.
    The preceding isintended 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, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2021 Oracle and/or its affiliates.