Posts SQL基础——主键设计
Post
Cancel

SQL基础——主键设计

主键设计

ROWNUM 和 ROWID(Oracle特有)

ROWID

特点:唯一,且固定,是在行数据生成时产生的id;

1
2
3
4
5
6
select rowid, empno from emp;
-- 此时的查询结果中,所有行的rowid字段是唯一的
select rowid, empno from emp where empno = 7369;
-- 该结果中
-- empno=7369的rowid 和 
-- 上一条 select 语句结果中empno=7369的rowid 相同

ROWID是永远不变的, 永远跟行记录走,不因查询条件而变化

ROWNUM

特点:一个伪列,对查询结果返回的行编号即行号,由1开始 依次递增

-- 返回该表全部14条数据
select rownum, emp.* from emp; -- 结果的rownum为1-14
-- 返回部门号为30的6条数据
select rownum, emp.* from emp where deptno = 30; -- 结果的rownum为1-6
-- 选取rownum的前五条数据
select rownum, emp.* from emp where rownum < 5;

ROWNUM数值是在获取每行之后才赋予的。

且:在 order by 之前赋予

要想在 order by 之后进行 rownum 的赋值,则只能:

1
2
3
4
5
select rownum, T.* from 
	(
    	select * from emp order by sal
    ) T
    where rownum < 5
分页问题
1
2
3
4
5
select rownum, T.* from
	(
    	select * from emp order by '一些条件'
    )
    between 'page1' and 'page2'

SQUENCE序列 (自增)

首先要有 Create sequence 或者 create any sequence 权限

创建sequence对象

1
2
3
4
5
create sequence emp_sequence -- 'sequence名称(自拟)'
increment by 1 -- '每次增加的数量'
start with 1 -- '从几开始'
nomaxvalue -- '一直累加,不循环'
cache 10 -- '缓存大小'

sequence对象的查询使用

1
2
3
4
5
-- 自增查询:查一次当前这个sequence的数值就增一次
-- 增多少取决于创建时,用increment给其定义的大小
select emp_sequence.nextVal from dual;
-- 当前查询:无论查多少次都是和第一次查询一样的值
select emp_sequence.currval from dual;

sequence对象的插入使用

1
2
3
-- 一半都是使用nextval插入,保证使用该序列的表不会拥有相同的一个id值
insert into dept(deptno, dname, loc)
	values (emp_sequence.nextval, 'PROGRSAMER', 'BEIJING');

使用sequence序列号时需注意:

  • 序列号只是用于保证某一列为唯一整数的方法。

  • 不要试图赋予它更多的意义。如:

    • 试图保证其连续性

      如下情况会导致序列号的值不连续。

      1. 回滚
      2. 系统错误,导致数据添加失败
      3. 同一个sequence序列对象用于多张表

一般sequence都是以主键的形式使用,一张表一个sequence对象

主键生成方式

sequence

​ 由Sequence对象生成一个不重复的整数。

其他数据库如:sqlserve、mysql 有一个identity类型的自增字段。

UUID

UUID简介

由四个连字号(-)将32个字节长的字符串分割后生成的字符串,一共36个字节。

比如:550e8400-e29b-41d4-a716-446644330000

UUID实现方式GUID

Oracle中生成UUID的函数为:sys_guid()

1
2
3
4
5
6
7
8
9
10
-- PL/SQL 编辑器的话,生成的就是一个正常的uuid
select sys_guid() from dual;
insert into emp(...)
	values(sys_guid()...)
-- 但如果用的其他客户端的话,生成的可能时乱码
-- 这是需要加上:rawtohex()
select rawtohex(sys_guid()) from dual;

insert into emp(...)
	values(rawtohex(sys_guid())...)

Java 中使用uuid

1
2
3
4
5
import java.util.UUID;

String uuid = UUID.randomUUID();
uuid = uuid.replaceALL("-", "");
System.out.println(uuid)

UUID 只起到维护表之间关联关系的作用。

为什么不使用业务字段作为主键

如:学号、产品号、工号。。。

因为:业务上的标识是有可能会更改的,而主键大部分情况可能会作为其他表的外键,如果用业务字段作为主键,当这些业务字段更改时,会很麻烦

This post is licensed under CC BY 4.0 by the author.