我正在与一名契约(Contract)开发人员合作,他开始在没有定义主键的情况下创建表 (MySQL)。相反,他定义了一个带有 UNIQUE 约束和 AUTO_INCREMENT 的列。我以前从未见过这样做,所以我想了解以这种方式定义表的含义。 一个缺点是无法在需要时创建外键。以这种方式创建表还有其他一些影响,无论好坏。也许我在这里漏掉了一个概念……
最佳答案
在没有显式主键的情况下定义 MySQL 是一个非常非常糟糕的主意。
如果缺少 PK,MySQL 将创建一个隐式(但非常真实)整数自增主键。
此 PK 将包含在 InnoDB 中的每个辅助键中,并将确定您在 MyISAM 中的主要排序顺序。
后果
您刚刚降低了每次选择、插入和更新的性能。
没有任何目的。
InnoDB:获取表数据需要额外查找
在 InnoDB 中,需要进行额外的查找,因为所有二级索引都引用 PK 而不是行本身。
MyISAM:浪费空间
在 MyISAM 中,惩罚不是那么大,但您仍然拖着一个未使用的 4 字节未使用字段。
InnoDB + MyISAM:自增字段的无用生成
因为创建了一个隐式自动递增 PK,并且您还需要一个额外的自动递增键来进行连接;为了防止重复的自动增量字段,现在每个插入有 2 个而不是 1 个表锁。
InnoDB: with joins the lookup probem above mentioned
如果您使用不是 PK 的字段进行连接,则 InnoDB 需要每次连接 进行额外的查找以获取其他表的记录。
InnoDB:最糟糕的是你失去了覆盖索引的好处
你已经禁用了 InnoDB 中最好的优化之一,覆盖索引。
如果 MySQL 可以只使用索引中的数据解析查询,它就永远不会读取表,这将导致显着的速度提升。既然 InnoDB 中每个索引的 50% 是未使用的空间,您就失去了使用该优化的机会。
请用线索棒打败这个承包商!
链接:
http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/ (链接慢,但推荐阅读)
O'Reilly on InnoDB's covering indexes
http://tag1consulting.com/MySQL_Engines_MyISAM_vs_InnoDB
顺便说一句,如果你的承包商说,这并不重要,因为他正在使用 MyISAM,再打败他,你应该总是使用 InnoDB,除非你有充分的理由不用。
InnoDB 在生产中要安全得多,MyISAM 有它的用途,但太容易被破坏。
关于MySQL 将列定义为具有 AUTO_INCREMENT 的 UNIQUE 而不是作为主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6180167/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve
我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)