Tag: 数据库

mysql – MyISAM与InnoDB

我正在研究涉及大量数据库写入的项目,我会说(70%的插入和30%的读取)。该比率还包括我认为是一次读取和一次写入的更新。读取可能很脏(例如,在读取时我不需要100%准确的信息)。 有问题的任务将是每小时进行超过100万次数据库事务。 我在网上看到了很多关于MyISAM和InnoDB之间差异的东西,对于我将用于此任务的特定数据库/表,MyISAM似乎是我的明显选择。从我似乎正在阅读的内容来看,如果需要事务处理,InnoDB很好,因为支持行级锁定。 有没有人有这种负载(或更高)的经验?MyISAM是走的路吗? 答案 我在表格中简要地讨论过这个问题,这样你就可以得出结论是否与InnoDB或MyISAM一起使用。 以下是您应该在哪种情况下使用哪个数据库存储引擎的小概述: MyISAM InnoDB -------------------------------------------------- -------------- 必需的全文搜索是5.6.4 -------------------------------------------------- -------------- 需要交易是的 -------------------------------------------------- -------------- 经常选择查询是 -------------------------------------------------- -------------- 频繁插入,更新,删除是 -------------------------------------------------- -------------- 行锁定(单表上的多处理)是 -------------------------------------------------- -------------- 关系基础设计是的 总结一下: 经常阅读,几乎没有写作=> MyISAM MySQL中的全文搜索<= 5.5 => MyISAM 在所有其他情况下,InnoDB通常是最好的方式。 我不是数据库专家,我不会从经验中说话。然而: MyISAM表使用表级锁定。根据您的流量估算值,您每秒接近200次写入。使用MyISAM,其中只有一个可以随时进行。您必须确保您的硬件能够跟上这些事务以避免被超出,即单个查询可能不会超过5毫秒。 这对我来说,你需要一个支持行级锁定的存储引擎,即InnoDB。 另一方面,编写一些简单的脚本来模拟每个存储引擎的负载应该是相当简单的,然后比较结果。 人们经常谈论性能,读取与写入,外键等等,但在我看来,存储引擎还有另外一个必备功能: 原子更新。 尝试这个: 对MyISAM表发出UPDATE需要5秒钟。 当UPDATE正在进行时,比如说2.5秒,按Ctrl-C中断它。 观察桌子上的效果。更新了多少行?有多少人没有更新?表格是否可读,或者当您按下Ctrl-C时它是否已损坏? 针对InnoDB表尝试使用UPDATE进行相同的实验,中断正在进行的查询。 观察InnoDB表。 零行已更新。InnoDB已确保您拥有原子更新,如果无法提交完整更新,则会回滚整个更改。此外,该表没有损坏。即使您使用killall -9 mysqld模拟崩溃,这也有效。 当然,性能是可取的,但不会丢失数据应该胜过它。 我使用MySQL工作的大容量系统,我已经尝试了MyISAM和InnoDB。 我发现MyISAM中的表级锁定导致了我们工作负载的严重性能问题,这听起来与您的相似。不幸的是,我还发现InnoDB下的表现也比我希望的要糟糕。 最后,我通过对数据进行分段来解决争用问题,使得插入进入“热”表并选择从不查询热表。 这也允许删除(数据是时间敏感的,我们只保留X天价值)发生在“陈旧”表上,这些表再次未被选择查询触及。InnoDB似乎在批量删除方面表现不佳,因此如果您计划清除数据,您可能希望以旧数据处于陈旧表中的方式对其进行构造,这样可以简单地删除而不是在其上运行删除。 当然我不知道你的应用程序是什么,但希望这能让你深入了解MyISAM和InnoDB的一些问题。 游戏有点晚……但这是几个月前写的一篇相当全面的文章,详细介绍了MYISAM和InnoDB之间的主要区别。拿一杯茶(也许是一块饼干),享受吧。

“INNER JOIN”和“OUTER JOIN”有什么区别?

又如何做LEFT JOIN,RIGHT JOIN并FULL JOIN适应? 假设你正在加入没有重复的列,这是一个非常常见的情况: A和B的内部连接给出A相交B的结果,即维恩图交点的内部部分。 A和B的外部连接给出了A联合B的结果,即维恩图联合的外部部分。 例子 假设你有两个表格,每个表格有一列,数据如下: A B - - 1 3 2 4 3 5 4 6 请注意,(1,2)对于A是唯一的,(3,4)是常见的,而(5,6)对于B是唯一的。 内部联接 使用等效查询中的任何一个的内部联接给出两个表的交集,即它们具有共同的两个行。 select * from a INNER JOIN b on a.a = b.b; select a.*, b.* from a,b where a.a = b.b; a | b --+-- 3 | 3 4 | 4 左外连接

为什么我不应该在PHP中使用mysql_ *函数?

为什么不应该使用mysql_*函数的技术原因是什么?(例如mysql_query(),mysql_connect()或mysql_real_escape_string())? 为什么我应该使用别的东西,即使他们在我的网站上工作? 如果他们不在我的网站上工作,为什么我会得到类似的错误 警告:mysql_connect():没有这样的文件或目录 答案 MySQL扩展: 没有积极发展 被正式弃用的PHP 5.5(发布2013年6月)。 已经删除全部为PHP 7.0(发布2015年12月) 这意味着截至2018年12月31日,它不会存在于任何受支持的PHP版本中。目前,它只获取安全更新。 缺少OO界面 不支持: 非阻塞异步查询 编写语句或参数化查询 存储过程 多重陈述 交易 “新”密码认证方法(在MySQL 5.6中默认开启;在5.7中需要) MySQL 5.1中的所有功能 由于它已被废弃,因此使用它会使您的代码不再适用于未来。 对准备好的语句缺乏支持尤其重要,因为它们提供了一种更清晰,更容易出错的转义和引用外部数据的方法,而不是通过单独的函数调用手动转义它。 查看SQL扩展的比较。 PHP提供了三种不同的API来连接到MySQL。这些是mysql(从PHP 7中删除)mysqli和PDO扩展。 这些mysql_*功能曾经非常流行,但不再鼓励使用它们。文档小组正在讨论数据库安全情况,并教育用户摆脱常用的ext / mysql扩展,这是(检查php.internals:deprecating ext / mysql)的一部分。 而后来的PHP开发团队已产生决定E_DEPRECATED当用户连接到MySQL的错误,无论是通过mysql_connect(),mysql_pconnect()或内置于隐式连接功能ext/mysql。 ext/mysql被正式弃用PHP 5.5的,并已为PHP 7的去除。 看到红盒? 当你进入任何mysql_*功能手册页时,你会看到一个红色的框,解释它不应该再被使用。 为什么 离开ext/mysql不仅仅关乎安全性,而且关于访问MySQL数据库的所有功能。 ext/mysql是为MySQL 3.23构建的,从那时起只有很少的新增功能,而且大部分时间保持与旧版本的兼容性,这使得代码难以维护。缺少不支持的功能ext/mysqlinclude 🙁 来自PHP手册)。 存储过程(不能处理多个结果集) 准备好的陈述 加密(SSL) 压缩 完整的字符集支持 不使用mysql_*功能的原因: 没有积极发展 从PHP 7中删除 缺少OO界面

数据库索引如何工作?

鉴于索引是非常重要的,因为你的数据集的规模增加了,有人可以解释索引如何在数据库无关的层面上工作吗? 有关索引字段的查询的信息,请查看如何索引数据库列。 答案 为什么需要? 当数据存储在基于磁盘的存储设备上时,它将作为数据块存储。这些块被完整访问,使它们成为原子磁盘访问操作。磁盘块的结构与链接列表非常相似,都包含数据部分,指向下一个节点(或块)位置的指针,并且都不需要连续存储。 由于许多记录只能在一个字段上排序,所以我们可以声明,在未排序的字段上搜索需要线性搜索,它需要N/2块访问(平均),N块的数量在哪里桌子横跨。如果该字段是非关键字段(即不包含唯一条目),则必须在N块访问时搜索整个表空间。 而对于排序的字段,可以使用二进制搜索,其具有log2 N块访问。此外,由于数据是在给定非关键字段的情况下进行排序的,因此一旦找到更高的值,表格的其余部分就不需要搜索重复值。因此,性能增加是相当大的。 什么是索引? 索引是一种对多个字段上的多个记录进行排序的方法。在表中的字段上创建索引会创建另一个数据结构,该结构保存字段值以及指向与其相关的记录的指针。然后对索引结构进行排序,从而对其执行二进制搜索。 索引的缺点是这些索引在磁盘上需要额外的空间,因为索引使用MyISAM引擎一起存储在一个表中,如果同一个表中的许多字段是相同的,那么该文件可以快速达到底层文件系统的大小限制索引。 它是如何工作的? 首先,让我们概述一个示例数据库表模式; 字段名称数据类型磁盘上的大小 id(主键)无符号整数4字节 firstName Char(50)50个字节 姓氏字符(50)50个字节 emailAddress字符(100)100个字节 注意:字符被用来代替varchar以允许磁盘值的准确大小。此样本数据库包含500万行,并且未进行索引。现在将分析几个查询的性能。这些是使用id(排序的关键字段)的查询和使用firstName(非关键字未排序的字段)的查询。 示例1 –分类与未排序的字段 鉴于我们的示例数据库中r = 5,000,000记录的固定大小给出了记录的R = 204字节长度,并且它们使用MyISAM引擎存储在表中,该引擎使用默认块大小B = 1,024字节。该表的阻止因子将是bfr = (B/R) = 1024/204 = 5每个磁盘块的记录。保持表格所需的块的总数是N = (r/bfr) = 5000000/5 = 1,000,000块。 如果N/2 = 500,000id字段是关键字段,那么对id字段进行线性搜索需要平均访问块来查找值。但是由于id字段也被排序,所以可以进行二分搜索,要求平均log2 1000000 = 19.93 = 20访问块。瞬间我们可以看到这是一个巨大的改进。 现在,firstName字段既没有排序也没有关键字段,因此二进制搜索是不可能的,并且这些值也不是唯一的,并且因此该表格将需要搜索到末尾以进行精确的N = 1,000,000块访问。索引编制旨在纠正这种情况。 鉴于索引记录仅包含索引字段和指向原始记录的指针,因此它会比它指向的多字段记录更小。所以索引本身需要的磁盘块比原始表要少,因此需要更少的块访问来遍历。firstName字段上的索引模式概述如下; 字段名称数据类型磁盘上的大小 firstName Char(50)50个字节