自从我记得自己以来,我正在使用 LAMP (Linux+Apache+MySQL+PHP) 进行开发。但有一个问题困扰了我多年。我希望你能帮助我找到答案并指出正确的方向。这是我的挑战:
比方说,我们正在创建一个社区网站,我们允许我们的用户在该网站上注册。我们存储所有用户的 MySQL 表将如下所示:
CREATE TABLE `users` (
`uid` int(2) unsigned NOT NULL auto_increment COMMENT 'User ID',
`name` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL COMMENT 'Password is saved as a 32-bytes hash, never in plain text',
`email` varchar(64) NOT NULL,
`created` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of registration',
`updated` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of profile update, e.g. change of email',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
因此,从这个片段中您可以看到我们为每个新用户的“uid”字段设置了一个唯一且自动递增的字段。对于每一个好的和忠诚的社区网站,我们需要为用户提供完全删除他们的个人资料的可能性,如果他们想取消他们对我们社区的参与。
我的问题来了。假设我们有 3 个注册用户:Alice (uid = 1)、Bob (uid = 2) 和 Chris (uid = 3)。现在 Bob 想删除他的个人资料并停止使用我们的社区。如果我们从 'users' 表中删除 Bob 的个人资料,那么他丢失的 'uid' 将创建一个永远不会被再次填充的空白。在我看来,这是对 uid 的巨大浪费。我在这里看到 3 种可能的解决方案:
1) 将表中“uid”字段的容量从 SMALLINT (int(2)) 增加到例如 BIGINT (int(8)),并忽略一些 uid 将被浪费的事实。
2) 引入新字段“is_deleted”,它将用于标记已删除的配置文件(但将它们保留在表中,而不是删除它们)以便为新注册的用户重新使用它们的 uid。该表将如下所示:
CREATE TABLE `users` (
`uid` int(2) unsigned NOT NULL auto_increment COMMENT 'User ID',
`name` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL COMMENT 'Password is saved as a 32-bytes hash, never in plain text',
`email` varchar(64) NOT NULL,
`is_deleted` int(1) unsigned NOT NULL default '0' COMMENT 'If equal to "1" then the profile has been deleted and will be re-used for new registrations',
`created` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of registration',
`updated` int(11) unsigned NOT NULL default '0' COMMENT 'Timestamp of profile update, e.g. change of email',
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
3) 编写一个脚本,在前一条记录被删除后转移所有后续用户记录。例如。在我们的例子中,当 Bob (uid = 2) 决定删除他的个人资料时,我们将用 Chris (uid = 3) 的记录替换他的记录,以便 Chris 的 uid 等于 2 并标记 (is_deleted = '1') Chris 的旧记录对新用户来说是空的。在这种情况下,我们根据注册时间保持uid的时间顺序,以便较旧的用户具有较低的uid。
现在请告诉我哪种方法是处理 auto_increment 字段中的间隙的正确方法。这只是用户的一个例子,但在我的编程经验中,这种情况经常发生。
提前致谢!
最佳答案
绝对不是移动用户 ID 的想法 - 这会在某个时候杀死你或你的 mysql 服务器。 假设您有 1,000,000 个用户,而用户 2 被删除了 - 您必须将 999,999 条记录向下移动一个...就像查询一样简单,它仍然会锁定您的数据库一段时间。 我还认为这会混淆您在每个表的每个插入上设置的 auto_increment 值。 插入 -> AI+1 -> 插入 -> AI+1 -> 删除 -> AI 保持不变...如果你移动所有 ID 的下一个 auto_increment 值仍然是 1,000,001,现在将 1,000,000 留空。
我说 unsigned BIGINT 并忽略它 - 因为如果你接近 bigint 的极限,你还有许多其他问题需要解决;)
关于php - MySQL 和 INT auto_increment 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2910698/
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
文章目录一、概述简介原理模块二、配置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
我几天前在我的rubyonrails2.3.2上安装了Sphinx和Thinking-Sphinx,基本搜索效果很好。这意味着,没有任何条件。现在,我想用一些条件过滤搜索。我有公告模型,索引如下所示:define_indexdoindexestitle,:as=>:title,:sortable=>trueindexesdescription,:as=>:description,:sortable=>trueend也许我错了,但我注意到只有当我将:sortable=>true语法添加到这些属性时,我才能将它们用作搜索条件。否则它找不到任何东西。现在,我还在使用acts_as_tag
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案
我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我
我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使