草庐IT

SQL语句 -非空约束 - 唯一约束 - 主键约束 - 默认约束 -外键约束

学全栈的灌汤包 2023-07-12 原文

文章目录

约束

约束介绍和分类

约束的概念:

约束是作用于表中列上的规则,用于限制加入表的数据

约束的存在保证了数据库中数据的正确性、有效性和完整性

约束的分类如下:

约束名称描述关键字
非空约束保证列中所有数据不能有null值NOT NULL
唯一约束保证列中所有数据各不相同UNIQUE
主键约束主键是一行数据的唯一标识, 要求非空且唯一PRIMARY KEY
检查约束保证列中的值满足某一条件CHECK
默认约束保存数据时, 未指定值则采用默认值DEFAULT
外检约束外键用来让两个表的数据之间建立连接, 保证数据的一致性和完整性FOREING KEY

注意: MySQL不支持检查约束

非空约束

概念: 非空约束用于保证列中所有数据不能有NULL值

语法:

添加约束:

-- 创建表时添加非空约束
CREATE TABLE 表名(
   列名 数据类型 NOT NULL,); 

-- 建完表后添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL;

删除约束:

ALTER TABLE 表名 MODIFY 字段名 数据类型;

唯一约束

概念: 唯一约束用于保证列中所有数据各不相同

语法:

添加约束:

-- 创建表时添加唯一约束
CREATE TABLE 表名(
   列名 数据类型 UNIQUE [AUTO_INCREMENT],
   -- AUTO_INCREMENT: 当不指定值时自动增长); 
CREATE TABLE 表名(
   列名 数据类型,[CONSTRAINT] [约束名称] UNIQUE(列名)
); 

-- 建完表后添加唯一约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE;

删除约束

ALTER TABLE 表名 DROP INDEX 字段名;

主键约束

概念:

主键是一行数据的唯一标识,要求非空且唯一

一张表只能有一个主键

语法:

添加约束: AUTO_INCREMENT表示主键自增

-- 创建表时添加主键约束
CREATE TABLE 表名(
   列名 数据类型 PRIMARY KEY [AUTO_INCREMENT],); 
CREATE TABLE 表名(
   列名 数据类型,
   [CONSTRAINT] [约束名称] PRIMARY KEY(列名)
);

-- 建完表后添加主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);

删除约束:

ALTER TABLE 表名 DROP PRIMARY KEY;

默认约束

概念: 保存数据时,未指定值则采用默认值

语法:

添加约束:

-- 创建表时添加默认约束
CREATE TABLE 表名(
   列名 数据类型 DEFAULT 默认值,); 

-- 建完表后添加默认约束
ALTER TABLE 表名 ALTER 列名 SET DEFAULT 默认值;

删除约束:

ALTER TABLE 表名 ALTER 列名 DROP DEFAULT;

案例练习

按照下面图片中的要求, 为表添加合适的约束:

语句演示:

CREATE TABLE emp (
	id INT PRIMARY KEY AUTO_INCREMENT,
	ename VARCHAR(50) NOT NULL UNIQUE,
	joindate DATE NOT NULL,
	salary DOUBLE(7,2) NOT NULL,
	bonus DOUBLE(7,2) DEFAULT 0
);

外键约束

概念: 外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性

语法:

添加约束:

-- 创建表时添加外键约束
CREATE TABLE 表名(
   列名 数据类型,[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名) 
); 

-- 建完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);

删除约束:

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

案例练习

例如我们有如下两张表, 员工表和部门表, 在没有添加外键约束的时候, 是可以直接删除部门表的研发部的;但是我们知道这是不合理的, 因为员工表中, 前三个员工是属于研发部的, 在有员工属于研发部的情况下应该不能删除才合理;

我们可以通过外键约束解决这个问题, 将两张表建立连接: 添加外键, emp表的dep_id关联dept表的id主键;

创建部门表(注意要先创建部门表), 将id设置为主键, 并添加两个部门

-- 部门表
CREATE TABLE dept(
	id INT PRIMARY KEY AUTO_INCREMENT,
	dep_name varchar(20),
	addr varchar(20)
);

-- 添加两个部门
INSERT INTO dept(dep_name, addr) VALUES('研发部','广州'),('销售部', '深圳');

创建员工表添加员工, 并为员工表emp添加外键约束

-- 员工表 
CREATE TABLE emp(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20),
	age INT,
	dep_id INT,

	-- 添加外键 dep_id,关联 dept 表的id主键
	CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
);

-- 添加员工,dep_id 表示员工所在的部门
INSERT INTO emp (NAME, age, dep_id) VALUES 
('张三', 20, 1),
('李四', 20, 1),
('王五', 20, 1),
('赵六', 20, 2),
('孙七', 22, 2),
('周八', 18, 2);

不需要可以删除外键

-- 删除外键
ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept;

建表后, 也是可以继续添加外键的

-- 添加外键
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id);

有关SQL语句 -非空约束 - 唯一约束 - 主键约束 - 默认约束 -外键约束的更多相关文章

  1. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  2. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  3. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  4. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  5. ruby - 如何在 Ruby 中向现有方法定义添加语句 - 2

    我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca

  6. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  7. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  8. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  9. ruby - ruby 乘法语句中星号中断语法前的空格 - 2

    在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl

  10. Ruby 默认将 IRB 配置为 Pretty_Inspect - 2

    我是ruby​​的新手,正在配置IRB。我喜欢pretty-print(需要'pp'),但总是输入pp来漂亮地打印它似乎很麻烦。我想做的是默认情况下让它漂亮地打印出来,所以如果我有一个var,比如说,'myvar',然后键入myvar,它会自动调用pretty_inspect而不是常规检查。我从哪里开始?理想情况下,我将能够向我的.irbrc文件添加一个自动调用的方法。有什么想法吗?谢谢! 最佳答案 irb中默认pretty-print对象正是hirb被迫去做。Theseposts解释hirb如何将几乎所有内容转换为ascii表。虽

随机推荐