PDO提供一个数据访问抽象层,意味着不管使用哪种数据库,都可以用同样一组API对数据进行操作,保证了可抽象性和访问接口的一致性
//连接数据库、创建数据库
php echo "使用PDO实例创建数据库
"; $servername = "localhost"; $username = "root"; $password = ""; try { $conn = new PDO("mysql:host=$servername;", $username, $password); echo "数据库连接成功
"; //设置PDO错误模式为异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "CREATE DATABASE myDBPDO"; //使用exec(),因为没有结果返回 $conn->exec($sql); echo "数据库创建成功
"; } catch(PDOException $e) { echo $sql . "
" . $e->getMessage(); } //关闭连接 $conn = null; ?>
//使用数据库,创建数据表
php $servername = "localhost"; $dbname = "myDBPDO"; $username = "root"; $password = ""; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); //设置PDO错误模式,用于抛出异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //使用sql创建数据表 $sql = "CREATE TABLE MyGuests ( id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, firstname VARCHAR(30) NOT NULL, lastname VARCHAR(30) NOT NULL, email VARCHAR(50), reg_date TIMESTAMP )"; //使用exec(),没有结果返回 $conn->exec($sql); echo "数据表MyGuests创建成功"; } catch(PDOException $e) { echo $sql . "
" . $e->getMessage(); } //关闭连接 $conn = null; ?>
//插入数据 php $servername = "localhost"; $username = "root"; $password = ""; $dbname = "myDBPDO"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); //设置PDO错误模式,用于抛出异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', '[email protected]')"; //使用exec(),没有结果返回 $conn->exec($sql); echo "新纪录插入成功"; } catch(PDOException $e) { echo $sql . "
" . $e->getMessage(); } $conn = null; ?>
//插入多条数据 php $servername = 'localhost'; $dbname = "myDBPDO"; $username = "root"; $password = ""; try{ $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); //set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //开始事务 $conn->beginTransaction(); //SQL语句 $conn->exec("INSERT INTO MyGuests (firstname, lastname, email) VALUES ('John', 'Doe', '[email protected]')"); $conn->exec("INSERT INTO MyGuests (firstname, lastname, email) VALUES ('Mary', 'Moe', '[email protected]')"); $conn->exec("INSERT INTO MyGuests (firstname, lastname, email) VALUES ('Julie', 'Dooley', '[email protected]')"); //提交事务 $conn->commit(); echo "新纪录插入成功"; } catch (PDOException $e) { //如果执行失败回滚 $conn->rollback(); echo $sql . "
" . $e->getMessage(); } $conn = null; ?>
//PHP MySQL预处理语句 //预处理语句对于防止MySQL注入是非常有用的 //预处理语句用于执行多个相同的SQL语句,并且执行效率更高 //预处理:创建SQL语句模板并发送到数据库。预留的值使用参数“?”标记 //INSERT INTO MyGusets (firstname, lastname, email) VALUES(?, ?, ?) //数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出 //执行:将应用绑定的值传递给参数(?标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样 //相比于直接执行SQL语句,预处理语句有两个主要优点: //预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。 //绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。 //预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。 php $servername = "localhost"; $dbname = "myDBPDO"; $username = "root"; $password = ""; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); //设置PDO错误模式为异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //预处理SQL并绑定参数 $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (:firstname, :lastname, :email)"); $stmt->bindParam(':firstname', $firstname); $stmt->bindParam(':lastname', $lastname); $stmt->bindParam(':email', $email); //插入行 $firstname = "John"; $lastname = "Doe"; $email = "[email protected]"; $stmt->execute(); //插入其他行 $firstname = "Mary"; $lastname = "Moe"; $email = "[email protected]"; $stmt->execute(); //插入其他行 $firstname = "Julie"; $lastname = "Dooley"; $email = "[email protected]"; $stmt->execute(); echo "新纪录插入成功"; } catch(PDOException $e) { echo "Error: ". $e->getMessage(); } $conn = null; ?>
//查询语句 php echo "
Id | Firstname | Lastname | " . parent::current(). " | "; } function beginChildren() { echo "
---|---|---|
数据库应用优化-->数据库的优化主要包括两个方面,一方面是SQL程序语句的优化,另一方面是数据库服务器和配置的优化
基本语句优化10个原则:
原则1:尽量避免在列上进行运算,这样会导致索引失效
原则2:使用JOIN时,应该用小结果集驱动大结果集,同时把复杂的JOIN查询拆分成多个Query。因为JOIN多个表时,可能导致更多的锁定和阻塞
原则3:注意LIKE模糊查询的使用,避免%%
原则4:仅列出需要查询的字段,这对速度不会有明显影响,主要考虑节省内存
原则5:使用批量插入语句节省交互
原则6:limit的基数比较大时使用between between限定比limit快,所以在海量数据访问时,建议用between或是where替换掉limit。但是between也有缺陷,如果id中间有断行或是中间部分id不读取的情况,总读取的数量会少于预计数量。在读取比较后面的数据时,通过desc方式把数据反向查找,以减少对前段数据的扫描,让limit的基数越小越好
原则7:不要使用rand函数获取多条随机记录
原则8:避免使用NULL
原则9:不要使用count(id),而应该是count(*)
原则10:不要做无谓的排序操作,而应尽可能在索引中完成排序
MySQL执行计划就是在一条SELECT语句前放上关键词EXPLAIN,MYSQL解释它将如何处理SELECT,提供有关表如何联合和以什么次序联合的信息
服务器和配置的优化
MySQL在高并发下的性能瓶颈很明显,主要原因就是锁定机制导致的堵塞。而InnoDB在锁定机制上采用了行级锁,不同于MyISAM的表级锁,行级锁在锁定上带来的消耗大于表级锁,但是在系统并发访问量较高时,InnoDB整体性能远高于MyISAM。同时,InnoDB的索引不仅缓存索引本身,也缓存数据,所以InnoDB需要更大的内存
存储引擎的选择方法
通过在数据库中执行show global status得到系统当前状态。在这些变量中,形如Com_XXX的语句表示XXX语句执行的次数。Com_select表示SELECT语句执行的次数。读写类型的比例,理想为100:1,当读写比达到10:1的时候,就认为是以读为主的数据库。
选择存储引擎的基本原则:
(1)采用MyISAM引擎:R/W>100:1且update相对较少;并发不高,不需要事务;表数据量小;硬件资源有限
(2)采用InnoDB引擎:R/W比较小,频繁更新大字段;表数据量超过1000万,并发高;安全性和可用性要求高
(3)采用Memory引擎:有足够的内存;对数据一致性要求不高,如在线人数和Session等应用;需要定期归档的数据
数据库分区
分区就是把一个数据表的文件和索引分散存储在不同的物理文件中,MySQL支持的分区类型包括Range、List、Hash、Key