SQLite---使用约束

背景

在使用SQLite建表的时候,通常会使用_id作为唯一标示,使用PRIMARY KEYAUTOCREMENT进行修饰,而主键是不可以重复的。但是在这张表中还有其他的Column也不允许重复,则可以使用Unique约束。

常用的约束有:

  • Unique:确保该列中的所有值是不同的
  • Not Null:确保被该约束修饰的列不会有空值
  • Default:当该字段没有值时,使用默认值填充
  • Primary Key:确保该列可以唯一标示一条数据,不会重复
  • Check:确保该列的值都满足条件,如果不满足,则无法插入

举例

现在有一张表,记录了本设备最近使用的App历史记录,并且按照进入的时间进行排序显示。当同一个App重复进入的时候,则需要覆盖原有Row。

那么这张表拥有四列:

  • _id:自增标志ID
  • app_name:访问的APP名,必须唯一
  • access_time:访问时间
  • access_count:访问次数,检测值必须大于0次

步骤

  • 在建表时,为唯一列设置Unique属性
  • 在建表时,加入Conflict处理策略
  • 在插入时,决定Conflict处理策略

注意:无论是建表时决定Conflict的处理策略还是插入时决定处理策略,Unique属性都是必须的

建表实现

创建app_access_table表,其中:

  • _id:使用Primary Key约束,自增
  • app_name:使用Unique,当有冲突时,则替换该条
  • access_time:使用Default约束,默认值为10000
  • aacess_count:使用Check约束,检查是否大于0
CREATE TABLE IF NOT EXISTS app_access_table (
      _id INTEGER PRIMARY KEY AUTOINCREMENT ,
      app_name TEXT UNIQUE ON CONFLICT REPLACE ,
      access_time LONG DEFAULT 10000 ,
      access_count INTEGER CHECK(access_count>0)
)

该建表语句决定了,当有新数据插入时,如果有相同app_name的话,则使用Replace策略替换原有数据

插入实现

创建app_access_table表,其中:

  • _id:主键,自增
  • app_name:只有Unique约束
  • access_time:默认值为10000
CREATE TABLE IF NOT EXISTS app_access_table (
      _id INTEGER PRIMARY KEY AUTOINCREMENT ,
      app_name TEXT UNIQUE ,
      access_time LONG DEFAULT 10000 ,
      access_count INTEGER CHECK(access_count>0)
)

在数据插入时使用insertWithOnConflict来决定冲突时,该如何处理,此处使用SQLiteDatabase.CONFLICT_REPLACE来决定数据冲突时,替换该条数据

db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);

值得注意的是,SQLiteDatabase在面对Replace的处理是,首先删除原有的行,然后再把新的这一行添加到表中,替换完后,_id字段会发生变化。

其他处理策略:

  • CONFLICT_ROLLBACK =1 当冲突发生时,立即回滚,结束当前的Transaction,并且会返回SQLITE_CONSTRAINT错误码。如果没有Transaction的话,那么就和ABORT一样
  • CONFLICT_ABORT = 2 当冲突发生时,不会执行Rollback,而会保留之前的数据。这是默认行为
  • CONFLICT_FAIL =3 当冲突发生时,命令中断,并且返回SQLITE_CONSTRAINT错误码。但是之前对数据库修改的命令都会保留,不会回退
  • CONFLICT_IGNORE = 4 当冲突发生时,该列不会插入也不会修改,并且命令继续正常执行。之前和之后的命令都不会受到影响,并且也不会有错误码返回。
  • CONFLICT_REPLACE = 5 当使用了UNIQUE约束的列发生冲突的时候,之前已经存在的行都会被删除掉,然后再插入/更新当前的列。因此插入/更新总会发生。命令也会继续执行,不会有错误返回。 如果发生在NOT NULL约束的列,那么NULL值会被默认值替换掉。如果该列没有默认值的话,那么就会使用ABORT策略。 如果发生在CHECK约束的列,则会使用IGNORE策略。 当这种策略触发删除row的时候,它不会触发delete trigger

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PHP在线

MySQL SQL语句优化的10条建议

1、将经常要用到的字段(比如经常要用这些字段来排序,或者用来做搜索),则最好将这些字段设为索引 2、字段的种类尽可能用int或者tinyint类型。另外字段尽可...

34350
来自专栏跟着阿笨一起玩NET

Oracle数据库自我总结

1.Oracle连接远程服务器,需要安装客户端的同时需要覆盖D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN\tnsnam...

10320
来自专栏Android Note

Android—Room数据库(介绍)

17050
来自专栏黑泽君的专栏

day37_Spring学习笔记_05_CRM_01

CRM : custom releation manager 客户关系管理系统,用于维护客户和公司之间关系。 我们要做的是:学校 和 大家 之间关系。

8520
来自专栏JAVA高级架构

SQL性能优化梳理

前言 本文主要针对的是关系型数据数据库MySql。键值类数据库可以参考最简大数据Redis。先简单梳理下Mysql的基本概念,然后分创建时和查询时这两个阶段的优...

32270
来自专栏闻道于事

PL/SQL 编程(三 )程序包和包体,触发器,视图,索引

一、程序包和包体 程序包(package):存储在数据库中的一组子程序、变量定义。在包中的子程序可以被其它程序包或子程序调用。但如果声明的是局部子程序,则只能在...

34470
来自专栏玄魂工作室

CTF实战8 SQL注入漏洞

我们还是那句话先 重要声明 该培训中提及的技术只适用于合法CTF比赛和有合法授权的渗透测试,请勿用于其他非法用途,如用作其他非法用途与本文作者无关

24820
来自专栏Linyb极客之路

不要这样写SQL 改掉这些坏习惯

SQL是作为一个程序员接触得非常多的一种语言,但是,很多时候,我们会发现,有些SQL的执行效率异常的差,造成了数据库的负担。我们通过分析这些有问题的SQL,就可...

10940
来自专栏Java后端技术栈

MySQL开发规范与使用技巧总结

1.库名、表名、字段名必须使用小写字母,并采用下划线分割。 a)MySQL有配置参数lower_case_table_names,不可动态更改,Linux系统...

12130
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十四天 Oracle学习【悟空教程】

ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S...

31420

扫码关注云+社区

领取腾讯云代金券