数据库修改主键的一些问题

alter table wp_commentmeta add PRIMARY key(meta_id);

Multiple primary key defined

表示定义了多个主键,需要把原来的主键先删除掉


ALTER TABLE wp_commentmeta DROP PRIMARY KEY;

Incorrect table definition; there can be only one auto column and it must be defined as a key

需要参数主键的自动增长

下面是修改主键的具体步骤

//去掉字段的自动增长
alter table wp_commentmeta modify meta_id int not null;

//删除主键
ALTER TABLE wp_commentmeta DROP PRIMARY KEY;

//建立新的主键
alter table wp_commentmeta add PRIMARY key(meta_id,comment_id);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高并发分布式系统中生成全局唯一Id汇总 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题。 单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求: 1 不能有单点故障。 2 以时间为序,或者ID里包含时间。这样一是可以少一个索引,二是冷热数据容易分离。 3 可以控制ShardingId。比如某一个用户的文章要放在同一个分片内,这样查询效率高,修改也容易。 4 不要太长,最好64bit。使用long比较好操作,如果是96bit,那就要各种移位相当的不方便,还有可能有些组件不能支持这么大的ID。 一 twitter twitter在把存储系统从MySQL迁移到Cassandra的过程中由于Cassandra有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。 1 41位的时间序列(精确到毫秒,41位的长度可以使用69年) 2 10位的机器标识(10位的长度最多支持部署1024个节点) 3 12位的计数顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号) 最高位是符号位,始终为0。 优点:高性能,低延迟;独立的应用;按时间有序。 缺点:需要独立的开发和部署。 原理 java 实现代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 public class IdWorker { private final long workerId; private final static long twepoch = 1288834974657L; private long sequence = 0L; private final static long workerIdBits = 4L; public final static long maxWorkerId = -1L ^ -1L << workerIdBits; private final static long sequenceBits = 10L; private final static long workerIdShift = sequenceBits; private final static long timestampLeftShift = sequenceBits + workerIdBits; public final static long sequenceMask = -1L ^ -1L < this.maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format( "worker Id can't be greater than %d or less than 0", this.maxWorkerId)); } this.workerId = workerId; } public synchronized long nextId() { long timestamp = this.timeGen(); if (this.lastTimestamp == timestamp) { this.sequence = (this.sequence + 1) & this.sequenceMask; if (this.sequence == 0) { System.out.println("###########" + sequenceMask); timestamp = this.tilNextMillis(this.lastTimestamp); } } else { this.sequence = 0; } if (timestamp < this.lastTimestamp) { try { throw new Exception( String.format( "Clock moved backwards. Refusing to generate id for %d milliseconds", this.lastTimestamp - timestamp)); } catch (Exception e) { e.printStackTrace(); } } this.lastTimestamp = timestamp; long nextId = ((timestamp - twepoch << timestampLeftShift)) | (this.workerId << this.workerIdShift) | (this.sequence); System.out.println("timestamp:" + timestamp + ",timestampLeftShift:" + timestampLeftShift + ",nextId:" + nextId + ",workerId:" + workerId + ",sequence:" + sequence); return nextId; } private long tilNextMillis(final long lastTimestamp) { long timestamp = this.timeGen(); while (timestamp <= lastTimestamp) { timestamp = this.timeGen(); } return timestamp; } private long timeGen() { return System.currentTimeMillis(); } public static void main(String[] args){ IdWorker worker2 = new IdWorker(2); System.out.println(worker2.nextId()); } }
数据库主键设计原则 或许大家都设计过数据库,也为表定义过主键,今天我想阐述的是,应该如何正确的设计一个主键,在以往的一些资料中,都有提及到主键设计的原则. 我为此总结了一下: 1.是否要采用GUID作为主键 用GUID作主键有它的优势与不足.优势是GUID具有唯一性,在任何情况下,可以产生全球唯一的值.这是GUID最大的优势,也方便数据导入, 比如要求从另一个系统中把数据导入进来,那么,不用担心,导入时,导致主键冲突.不足是GUID值太复杂.不易记忆, 因为有时,难免我们用记录的方式,来进行记录判断.而且数据太长,影响数据库效率.GUID的产生不是以一定的次序产生, 对于按主键物理排序的数据库来说,如果在记录的前部插入一条记录,可能导致后面N次方的数据条数后移.这将导致数据插入效率. 因此GUID的采用应该要慎重. 2.是否要采用自动递增的方式 对于以前谈到的主键,要求唯一性,因此大家都用自动递增的方式.这样的方式是非常不可取的.可能是为了方便插入记录时,不必去人为创建主键值. 以为这样方便,其实不是的.带来的麻烦要远远胜于这种所谓的"方便".第一:数据导入不方便,经常有从另一系统导入数据进来,自动递增的主键, 将不允许原表中的ID被导入进来.这导致主键丢失.第二:对于象订单这样的有主外键的表来说,如果订单的"主档表"主键是自动生成的. 那么在保存一个订单时,要求对主档表与明细表同进行事务保存,而此时,先要生成一条订单,然后取出这个订单自动生成的主键, 然后再把此作为明细表的一个外键,进行明细的保存.这过程中,将变以复杂而且不可行.事务如何处理.订单主档表插入记录后, 要是明细保存时遇到错误,主档表记录还要进行删除.烦.插入成功以后,还要取出产生的最大值.这将是一个严重的浪费. 记录多的话影响速度,而且存在并行插入.导致获取的记录可能是不正确的. 因此在以上的严重问题下,请不要采用自动递增方式. 3.是否要采用int型作为主键 以前大家都采用int型,都是出来主键都是数字导致的.其实我们也明白.并不是只是数字的东西就是数字型的.比如电话号码等. 因此对于主键,采用 int型的优势是速度快,插入,查询时都可能比其他的方式快.但我这种快的效果也未必有多明显, 比如以varchar(15)为例,物理主键排序的数据,自动以主键进行物理数据排序.因此,就算是字符型的数据,在插入时也插入到相应的物理位置上, 也就是说,在插入时可能影响一些速度.但在以后的查询中,速度影响不太明显.而我要说的,不采用int型作为主键,不是说,里面不存数据. 我还是建议大家在主键中存放数字,这样的排序比较要比夹杂字母的排序来的快,之所以要采用字符型,也是为以后的数据导入作准备, 有一天,要求从其他表导入数据时,可以在导入数据的主键上加一个特定字母来避免与原主键冲突.比如在导入数据的主键前加一个"N"字母. 这也就不用担心,要求导入数据表中的主键是数字型还是字符型了. 4.是否采用编号来定义主键 这个问题是老生常谈了.主键设计有个原则,就是主键不应具有任何实际意义.这条其实是非常重要,有人就是觉得编号本身是唯一的, 可以作为主键用,但可能为以后带来麻烦.因为带有实际意义的字段,还是存在被修改的可能性.而对于主键最大的忌讳就是修改主键, 这可能导致非常严重的不可估计的后果.比如学生编号,平时以为永远不修改,但修改的可能还是存在. 还有一种,表面上是唯一的,但实际上应该是允许重复的.我举个例子,订单吧,订单编号应该是唯一吧.是的.可是存在这样的情况, 一张原来的订单是因为某个原因,要求订单作废.那好给订单的状态标识为"cancel".然后允许再次录入同样编号的订单. 因此.对于这样的情况下在,虽然有效的订单编号只有一个,但在数据库角度允许编号重复. 所以不管如何,还是建议大家为表都建一个有任何意义的主键,如ID. 因此,总结一下,我在设计主键采用字符型的.不采用自动递增,在新增记录时,系统生成主键值.一般为全数字进行存入, 至于主键值的生成规则,可以按需求进行规则定义.如果有特殊的要求, 只是为了保持唯一,可以定义一个字段存放一个数值.在生成时,自动加一.然后再存回去.这也比从一个表中寻找最大值要来的快吧. 目前一个比较好的主键是采用GUID,当然我是推荐主键还是字符型的,但值由GUID生成,GUID是可以自动生成,也可以程序生成 ,而且键值不可能重复,可以解决系统集成问题,几个系统的GUID值导到一起时,也不发生重复,就算有"o"老数据也可以区分,而且效率很高, 在.NET里可以直接使用System.Guid.NewGuid()进行生成,在SQL里也可以使用 NewID()生成。   优点是:   同 IDE

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值