为什么序列号查不到在每个基本表中要使用序列作为主键

如何使用序列作为一个表的主键值_百度知道
如何使用序列作为一个表的主键值
提问者采纳
直到指定的最大值为止。当一个序列第一次被查询调用时,可以使用序列自动产生主键的键值序列(Sequence)是一种可以被多个用户使用的用于产生一系列唯一数字的数据库对象:create sequence [模式]序列名称[start with 起始数字] [increment by 增量][maxvalue 最大值|nomaxvalue][minvalue 最小值|nominva lue][cycle|nocuyle][cache 数目|nocache][order|noorder]。 创建序列语法如下。序列定义存储在数据字典中。序列可以循环,或者是连续增加的。在随后的每次查询中,它将返回一个预定值,通过提供唯一数值的顺序表来简化程序设计工作,序列将产生一个按指定的增量增长的值
提问者评价
来自:求助得到的回答
其他类似问题
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁新浪广告共享计划>
广告共享计划
SQL&SERVER数据库表主键设计(一)
摘要:本文根据笔者在历往项目中的数据库表主键设计的情况,发现过去在主键设计上存在着不合理性。在此基础上,提出了新的主键设计思想和具体解决办法。该设计思路具有通用意义,针对大多数情况是一种行之有效的办法,具有现时的指导意义。
关键词:SQL Server 数据库
主键 序列 分页
当前,随着信息量的急剧增加,对于数据的存储和管理方式,各企业都逐渐摆脱了之前的依靠文件系统(文本文件或者Excel)或者一些桌面型的小型数据库系统(如Access、FoxBASE或者DBase)的状态,转而通过一些大型数据库来管理企业的信息。这些大型数据库系统包括Oracle、MS SQL Server或者IBM
DB2。尽管目前数据库系统也在向面向对象的数据库系统方向发展,但是上述的传统的关系型数据库系统依然占据着主要位置。
笔者从九十年代末开始以关系型数据库系统为基础为客户进行管理软件的定制化开发。主要是以PowerBuilder为前台开发工具,开发出一些列的C/S结构的软件。进入到本世纪,尤其是最近两年,笔者又以Visual Studio
2003为工具,开发了一些B/S结构的应用。但是,无论是使用何种开发工具,还是开发何种结构的软件,其后台数据库系统依旧是关系型数据库系统。根据客户的应用环境,主要是在MS SQL Server数据库上进行开发,当然也有基于Oracle数据库的软件开发。
也正是因为数据量信息量的增加,采用大型的关系型数据库系统作为企业的数据存储管理方式,也就要求基于数据库开发的开发者在数据库设计时必须遵循相应的规范。关于数据库逻辑设计,最重要的就是数据库表的设计,都有一套相应的理论支持,比如要满足相应的范式要求。一般而言,数据库表设计满足第二或者第三范式即可。
在开发过程中,也尽量遵循这些相应的规则,但由于之前的经验所限或者是在详细设计时做的工作不够充分,导致一些表结构不是很合理。正是这些不合理,目前出现一些问题,并且已经在部分系统中有所体现。
关于数据库的逻辑设计,是一个很广泛的问题。本文主要针对笔者开发应用中的现状,论述在MS SQL
Server上进行表设计时,对表的主键设计应注意的问题以及相应的解决办法。
主键设计现状和问题
关于数据库表的主键设计,一般而言,是根据业务需求情况,以业务逻辑为基础,形成主键。
比如,销售时要记录销售情况,一般需要两个表,一个是销售单的概要描述,记录诸如销售单号、总金额一类的情况,另外一个表记录每种商品的数量和金额。对于第一个表(主表),通常我们以单据号为主键;对于商品销售的明细表(从表),我们就需要将主表的单据号也放入到商品的明细表中,使其关联起来形成主从关系。同时该单据号与商品的编码一起,形成明细表的联合主键。这只是一般情况,我们稍微将这个问题延伸一下:假如在明细中,我们每种商品又可能以不同的价格方式销售。有部分按折扣价格销售,有部分按正常价格销售。要记录这些情况,那么我们就需要第三个表。而这第三个表的主键就需要第一个表的单据号以及第二个表的商品号再加上自身需要的信息一起构成联合主键;又或者其他情况,在第一个主表中,本身就是以联合方式构成联合主键,那么也需要在从表中将主表的多个字段添加进来联合在一起形成自己的主键。
笔者在以前的项目中,也基本上是采取这样的表设计思路来设计系统的表结构和主键。
存在的问题
在上面小节中,我们描述了当前在表的主键设计时的现状。从中我们不难看出存在这样的问题:
数据冗余存储:随着这种主从关系的延伸,数据库中需要重复存储的数据将变得越来越庞大。或者当主表本身就是联合主键时,就必须在从表中将所有的字段重新存储一次。
SQL复杂度增加:当存在多个字段的联合主键时,我们需要将主表的多个字段与子表的多个字段关联以获取满足某些条件的所有详细情况记录。
程序复杂度增加:可能需要传递多个参数。
效率降低:数据库系统需要判断更多的条件,SQL语句长度增加。同时,联合主键自动生成联合索引
WEB分页困难:由于是联合主键方式(对于多数的子表),那么在WEB页面上要进行分页处理时,在自关联时,难于处理。
从上面,我们已经看到现有结构存在着相当多的弊端,主要是导致程序复杂、效率降低并且不利于分页。
为解决上述问题,本文提出:当应用系统后台数据库表间存在主从关系时,数据库表额外增加一非业务字段作为主键,该字段为数值型;或者当该表需要在应用中进行分页查询时,也应考虑如此设计。一般地,我们也可以几乎为任何表增加一个与业务逻辑无关的字段作为该表的主键字段。
字段定义方式
由于该字段要作为表的主键,那么其首要条件是要保证在该表中要具有唯一性。同时,结合SQL
Server数据库自身的特性,可以为其建立一个自增列:
CREATE TABLE T_PK_DEMO
U_ID&&&&&&&
&&&&&&&&&NOT
NULL IDENTITY(1,1),--唯一标识记录的ID
&&& COL_OTHER&
VARCHAR(20)&&&&
&&&&&&&&&&&&&,--其他列
&&& CONSTRAINT PK_T_PK_DEMO
PRIMARY KEY
&NONCLUSTERED (U_ID)--定义为主键
Server中的自增列却存在一个比较尴尬的事实,那就是该字段一旦定义和使用,用户无法直接干预该字段的值,完全由数据库系统自身控制:
完全数据库系统控制,用户无法修改值
在数据库的发布和订阅时,使用自增列会比较麻烦
恢复部分数据时,使用自增列会比较麻烦
该列的值必须在插入数据后才能获取
鉴于此,建议不以自增列的方式来定义,而是参考Oracle数据库系统中序列,在SQL Server系统中实现类似Oracle数据库系统序列功能。这个具体在下面的小节中介绍。我们只需要按照普通字段的定义方式修改表定义为:
CREATE TABLE T_PK_DEMO
U_ID&&&&&&&
&&&&&&&&NOT
NULL ,--唯一标识记录的ID
&&& COL_OTHER&
VARCHAR(20)&&&&
&&& CONSTRAINT PK_T_PK_DEMO
PRIMARY KEY
&NONCLUSTERED (U_ID)--定义为主键
序列的实现
参照Oracle序列的功能,我们需要在SQL Server数据库中创建一个新表,以管理序列值:
CREATE TABLE T_DB_SEQ
SEQ_NAME&&&&&&&
VARCHAR(50)&&&&
&&&&&&&&&&&&&,--序列名称
SEQ_OWNER&&&&&&
VARCHAR(50)&&&&
NOT NULL DEFAULT
'DBO',--序列所有者(SYSTEM_USER)
SEQ_CURRENT&&&&
BIGINT&&&&&&&&&
NOT NULL DEFAULT
0&&& ,--序列当前值
SEQ_MIN&&&&&&&&
BIGINT&&&&&&&&&
NOT NULL DEFAULT
0&&& ,--序列最小值
SEQ_MAX&&&&&&&&
BIGINT&&&&&&&&
NULL DEFAULT 0&&& ,--序列最小值
SEQ_MAX&&&&&&&&
BIGINT&&&&&&&&&
NOT NULL DEFAULT
0&&& ,--序列最大值
SEQ_STEP&&&&&&&
&&&&&&&&&&&&NOT
NULL DEFAULT 1&&& ,--序列增长步长
IF_CYCLE&&&&&&&
&&&&&&&&&&&&NOT
NULL DEFAULT 0&&& ,--是否循环(0,不循环;1,循环)
&&& CONSTRAINT T_DB_SEQ
PRIMARY KEY
&CLUSTERED
(SEQ_NAME,SEQ_OWNER)--主键
应用系统为需要创建自增列的表创建一个序列名称,在表“T_DB_SEQ”中反映为数据库中的一行。
第一,需要为需要建立序列的表创建一个序列。采用方法:F_CREATE_SEQ(序列名)。该函数传入序列的名称,在表“T_DB_SEQ”插入一行。序列的所有者,采用系统变量SYSTEM_USER。
第二,获取下一个值。采用方法:F_GET_NEXT_SEQ_VAL(序列名)。该函数根据序列名获取该序列的下一个值,根据当前值与增长步长得到。同时,该函数保证在同时获取同一个序列时,应保证并发一致性。
第三、将返回值返回到应用使用。
此外,为保证应用的完整性,可能还需要提供一些方法的重载方法,同时提供一些其他方法:
获取序列当前值:F_GET_SEQ_CUR_VAL(序列名)
设置序列值:F_SET_SEQ_VAL(序列名)
删除序列:F_DEL_SEQ(序列名)
判断序列是否存在:F_SEQ_EXISTS(序列名)
在主从关系的表设计中,子表也使用序列字段作为唯一主键,将父表的序列字段作为外键关联:
CREATE TABLE T_PK_DEMO_C
U_ID&&&&&&&
&&&&&&&&NOT
NULL ,--唯一标识记录的ID
COL_OTHER& VARCHAR(20)&&&&
P_ID&&&&&& INT
&&&&&&&&&&&&NOT
NULL ,--父表ID
&&& CONSTRAINT PK_T_PK_DEMO_C
PRIMARY KEY
&NONCLUSTERED (U_ID)--定义为主键
CONSTRAINT
FK_T_PK_DEMO_C FOREIGN
KEY (P_ID) REFERENCES T_PK_DEMO(U_ID)
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。6:57:59【 转载互联网】 作者: &&|&责编:李强
&&& &为了解决用户可能碰到关于"hibernate连接oracle,生成主键要是用sequence,为什么还要设置oracle序列呀"相关的问题,突袭网经过收集整理为用户提供相关的解决办法,请注意,解决办法仅供参考,不代表本网同意其意见,如有任何问题请与本网联系。"hibernate连接oracle,生成主键要是用sequence,为什么还要设置oracle序列呀"相关的详细问题如下:序列怎么设置呀?怎么定义序列呀?===========突袭网收集的解决方案如下===========
解决方案1:generator&/&id name=&在oracle中执行下面的pl/param name=&实体属性名称& column=&
&sequence&主键名&seq_test&param&generator class=&id&&sequnece&&
&lt实体配置文件是这样&lt解决方案2:谢谢您的耐心解答,我受益匪浅!解决方案3:ya178帮帮团:hibernate用的sequence就是指定的oracle的sequence。你仔细看看配置就知道了!解决方案4:额?这个……我就是不太明白oracle的sequence,如果我在oracle不存在这个表,我用hibernate不是可以给我建立这个表么,那么如何定义oracle的sequence呀,怎么还会指定序列名呢?解决方案5:定义oracle的sequence 就是在oracle里建一个sequence啊!你看看这个配置:
&class name=&com.kay.pojo.Student& table=&STUDENT& schema=&KAY&&
&id name=&id& type=&java.lang.Long&&
&column name=&ID& precision=&22& scale=&0& /&
&generator class=&sequence&&
&param name=&sequence&&pk&/param&//pk为sequence名称
&/generator&
&property name=&name& type=&java.lang.String&&
&column name=&NAME& length=&50& /&
&/property&
&/class&还有一种方式是使用公共的sequence, 这各时候可以不指定表使用的sequence,那么相应的hbm.xml中内容是:  然后创建公用的 sequence对象,命名为 hibernate_sequence  create sequence hibernate_sequence  minvalue 0  maxvalue   start with 10000  increment by 1;
================可能对您有帮助================
问:我用myeclipse连接数据库自动生成hibernate文件,连接mysql是正常成功,...答:我用的eclipse编辑器,不知道你用的什么..说下我的做法. 首先要配一个连接池: eclipse工具栏上的窗口-&首选项-&MyEclipse-&Database Explore-&Drivers 在右边的选项卡中,先NEW,新建一个连接. 打开对话框,在第一下拉框中先择用的数据库,我用的是or...===========================================问:序列怎么设置呀?怎么定义序列呀?答:ya178帮帮团: hibernate用的sequence就是指定的oracle的sequence。 你仔细看看配置就知道了!===========================================问:序列怎么设置呀?怎么定义序列呀?答:你都没有指定oracle的序列捏。 sq_user 另外你的主键是id,这个是oracle的关键字,貌似会有问题。我觉得,改改比较好吧(比如说userId)。 ===========================================问:我在sqlplus中以system的用户帐号登录进入,然后在里面创建了一个表空间...答: jdbc:oracle:thin:@1521:oadb oracle.jdbc.driver.OracleDriver scott tiger "&org.hibernate.dialect.Oracle9Dialect true oadb为数据库名 表空间没有,只要数据库名即可===========================================问:看好多设置都是为了减少生成的语句。我这里只是为了保存一个用户和一个...答:性能的好坏是对比着来的。你这里指提供了一种方法,我也没想到更好的方法。所以,也没什么好坏的区别。 这里,除非你有更好的获得主键的方式来替代。 对数据库操作本身就是影响性能的,处理中,能减少对数据库操作的次数就减少。 另外,这种简单...===========================================问:急,在线等消息!!!答:其他当然要自己写了,生成的那些只是最基本的,你可与仿照生成的格式再上网查查资料写hql语句也行,写sql语句生成hql也行===========================================问:急,在线等消息!!!答:能吧你配置信息贴出来吗,从异常信息上看,你的数据库方言配置有问题,因为hibernate根据方言生成对应数据库的sql===========================================问:急,在线等消息!!!答:这个偶没用过,我想无非就帮你创建hibernate.xml吧你可以直接去hibernate.xml中修改啊 下边是随便写在一个类里边的,自己可以放在想要的地方首先你要找===========================================问:java使用hibernate连接oracle时,使用Configuration 的buildSessionFact...答:可能是数据库连接池配置错误(content.xml)!建议你把相关配置信息发上来看看。 在Oracle数据库连接池中应设置为“validationQuery="select 1 from dual"” ===========================================
12345678910第一,需要为需要建立序列的表创建一个序列。采用方法:F_create_SEQ(序列名)。该函数传入序列的名称,在表“T_DB_SEQ”插入一行。序列的所有者,采用系统变量SYSTEM_USER。
第二,获取下一个值。采用方法:F_GET_NEXT_SEQ_VAL(序列名)。该函数根据序列名获取该序列的下一个值,根据当前值与增长步长得到。同时,该函数保证在同时获取同一个序列时,应保证并发一致性。
第三、将返回值返回到应用使用。
此外,为保证应用的完整性,可能还需要提供一些方法的重载方法,同时提供一些其他方法:
获取序列当前值:F_GET_SEQ_CUR_VAL(序列名)
设置序列值:F_SET_SEQ_VAL(序列名)
删除序列:F_DEL_SEQ(序列名)
判断序列是否存在:F_SEQ_exists(序列名)
在主从关系的表设计中,子表也使用序列字段作为唯一主键,将父表的序列字段作为外键关联:
以下为引用的内容:
create TABLE T_PK_DEMO_C ( U_ID  BIGINT NOT NULL ,--唯一标识记录的ID COL_OTHER VARchar(20) NOT NULL ,--其他列 P_ID  INT NOT NULL ,--父表ID CONSTRAINT PK_T_PK_DEMO_C PRIMARY KEY NONCLUSTERED (U_ID)--定义为主键 CONSTRAINT FK_T_PK_DEMO_C FOREIGN KEY (P_ID) REFERENCES T_PK_DEMO(U_ID) ON delete CASCADE, )
使用序列的问题及解决办法
由于系统使用一个额外增加一个字段作为主键,因此没有为业务逻辑建立主键约束。比如在企业用户信息表中,要求企业中用户登录名必须唯一。一般在创建表时,以登录名作为主键,这个时候在数据库层自然的创建另一个主键唯一性约束。而现在没有使用登录名作为主键,那么就没有这个约束。解决办法:
一是在数据库层解决。可以为该表创建一个唯一(UNIQUE)约束或者唯一索引。如:
alter TABLE T_PK_DEMO ADD CONSTRAINT C_T_PK_DEMO UNIQUE NONCLUSTERED(COL_OTHER)-唯一约束
create UNIQUE INDEX IX_T_PK_DEMO ON T_PK_DEMO(COL_OTHER) C 唯一索引
二是在应用端解决。也就是在应用中判断该列是否有重复值,然后根据判断结果来保证唯一性。
我们注意到,在之前的例子中,主键采用了NONCLUSTERED(非聚蔟)的索引方式。关于如何设计索引,不是本文的重点,在这里仅提供一个建立索引时采用聚蔟方式还是非聚蔟方式的一个一般原则:
作为非业务字段的主键列,是一个没有重复值的、基本不进行更新操作的列。并且,在SQL Server数据库中,聚蔟索引在一个表中只能有一个。因此,聚蔟索引非常重要,需要留给更重要的字段来使用。因此,对照上表和根据聚蔟索引的重要程度,在此处采用非聚蔟方式创建其索引。
【】【】【】【】
ISBN编号:&8
出版时间:&2013-3
出版社:&中国人事出版社
定价:¥45 优惠价:¥45&&ISBN编号:&9
出版时间:&2013-4
出版社:&中国人事出版社
定价:¥45 优惠价:¥45&&
????????????
????????????
         Copyright ©
() All Rights Reserved

我要回帖

更多关于 mysql 主键 的文章

 

随机推荐