MySQL:设计数据库与操作
设计数据库
- 1. 数据建模
- 1.1 概念模型
- 1.2 逻辑模型
- 1.3 实体模型
- 主键
- 外键
- 外键约束
- 2. 标准化
- 2.1 第一范式
- 2.2 链接表
- 2.3 第二范式
- 2.4 第三范式
- 3. 数据库模型修改
- 3.1 模型的正向工程
- 3.2 同步数据库模型
- 3.3 模型的逆向工程
- 3.4 实际应用建议
- 4. 数据库实体模型
- 4.1 创建和删除数据库
- 4.2 创建表
- 4.3 更改表
- 4.4 创建关系
- 4.5 更改主键和外键约束
- 4.6 字符集和排序规则
- 4.7 存储引擎
1. 数据建模
数据建模的4个步骤:
- 理解需求
理解和分析商业/业务需求,遗憾是很多程序员跳过了这一步就急着去设计数据库里的表和列了,实际上,这一步是最关键的一步,你对问题理解的越透彻,你才越容易找到最合适的解决方案,设计数据库也一样。所以,在动手创建表和列之前,要先完整了解你的业务需求,包括和产品经理、行业专家、从业人员甚至终端用户深入交流以及收集查阅已有的领域相关的表、文件、应用程序、数据库,以及其他与问题领域相关的任何信息或资料。 - 概念建模
当收集并理解了所有相关信息后,下一步就是为业务创建一个概念性的模型。这一步包括找出/识别/确认(identify)业务中的实体/事务/概念(entities/things/concepts)以及它们之间的关系。概念模型只是这些概念的一个图形化表达,用来与利益相关方交流和达成共识。 - 逻辑建模
创建好概念模型后,转而创建数据模型(data model)或数据结构(data structure for storing data),即逻辑建模。这一步创建的是不依赖于具体数据库技术的抽象的数据模型,主要是确认所需要的表和列以及大体的数据类型。 - 实体建模
实体建模指的是将逻辑模型在具体某种DBMS上加以实现的过程,相比于逻辑模型,实体模型会确定更多细节,包括各表主键的设定,各列在某一DBMS下特定的具体的数据类型,默认值,是否可为空,还包括储存过程和触发器等对象的创建。总之,实体模型是在某一特定DBMS下对数据模型非常具体的实现。
1.1 概念模型
案例:建立学生实体并确定相关属性;建立课程实体并确定相关属性;建立两个实体之间的关系。如上图所示。
将实体及其关系可视化的方法,一种是实体关系图(Entity Relationship, ER),一种是统一建模语言(Unified Modeling Language,UML),这里我们用实体关系图(ER),这里采用工具为VISIO。
NOTE: 建模是个迭代过程,不可能第一次就建立完美模型,需要在理解需求和模型设计之间不断反复,多次调整。比如这里的学生属性,可以先确定个大概,之后可以根据需要再进行增删修改。
概念模型主要是从很高的视角来总览业务需求,识别业务中的实体/事务/概念以及他们彼此间的关系,通常这些实体包括人、事件、地点等。只是从概念上总揽全局,目的是和业务人员交流,保持理解一致。
1.2 逻辑模型
逻辑模型是在概念模型的基础上,在不依赖特定数据库系统的前提下确定数据结构,包括细化实体间的关系(常常要为关系创造新的实体),调整字段设置,确定大体的数据类型。总之,逻辑模型会基本确立数据库中的表、列以及表间关系。
对概念模型逻辑化的过程如下:
- 细化实体间关系
考虑学生和课程的关系,首先这是一种多对多关系(通常意味着需要进一步细化);这些属性相对于学生和课程而言都是一对多关系,不管放在学生还是课程身上都不合适,所以应该为学生和课程之间的关系,即注册课程的事件另外设立一个实体 enrollmemt,上面的注册日期和注册价格都应该是这个enrollment 注册事件的属性。 - 调整字段并大体确定字段的数据类型
姓名(name)最好拆分为姓和名 (first_name 和 last_name),同理,地址应该拆分为省、市、街道等等小的部分,这样方便查询。注意课程里的 tags 标签字段不是一个好的设计,之后讲归一化时再来处理。
这里的数据类型只需确定个大概即可,如:是 string,float 而非 VARCHAR, DECIMAL。等到下一步实体模型里再来确定某个DBMS下的具体数据类型。
1.3 实体模型
实体模型(实际模型)就是逻辑模型在具体DBMS的实现,这里我们用MySQL实现的逻辑模型。实体模型是逻辑模型在特定DBMS上的实现,主要是一些技术上的细化,包括确定字段具体数据类型和性质(能否为空等),设置主键等。
- 操作方法:Workbench-file-【new model】新建数据库,上方用 add diagram 作 EER 图,这里EER表示Enhanced Entity Relationship增强型实体关系图。为三个实体创建三张表,设定表名、字段、具体的数据类型、是否可为空(即是否为必须字段),也可以选择设定默认值(主键设定之后再讲)。
NOTE:
- 表名:之前逻辑模型里表名用单数,但这里表名用复数。这只是一种惯例,单复数都行,关键是要保持一致。
- 字段名:以enrollments表为例,注册事件的属性应该是dat日期和pric价格而非enrollment_date注册日期和enrollement_price注册价格,不要将表名前缀加上字段上造成不必要的麻烦,保持精简(keep thingssimple)。
- 数据类型:数据类型要根据业务需要来,例如,和业务人员确认后发现课程价格最高是999美元,所以price价格就可以设定为DECIMAL(5,2),之后如果需求变了了也可以随时更改,不要一上来就设定DECIMAL(9,2),浪费磁盘,注意保持精简(keep things small)
主键
主键就是能唯一标识表中每条记录的字段。(一般用数字ID来确定)
主键要短,可唯一标识记录,且永不改变。我们增加一个 student_id 作为主键,类型设为 INT(最大可表示2亿,一般足够了,但记得总是根据具体的需求决定),设为主键后自动变为不可为空,另外还要设定 AI(AutoIncremental)自动递增,这样会方便许多,不用担心主键唯一性的问题,最后我们把主键拖到表的第一列让表的结构看起来更清晰。
外键
实体模型需要更多得实现细节。
Note: 连线时记不得先连主表还是子表可以看状态栏的提示; MySQL自动添加的外键会带父表前缀,没必要,建议去掉.
注意 enrollments 表的特殊性,它可以说是 students 和 courses 的衍生表,先要有学生和课程,才能有学生注册课程这一事件,后者表述的是前两者的关系,学生和课程是因,注册课程这一事件是果。
MySQL里可以通过一对一或一对多两种连线表达这种先后关系/因果关系并自动建立外键,其中学生和课程被称作父表或主键表,注册事件被称作子表或外键表,外键是子表里对父表主键的引用。
根据表间关系给enrollments表添加了student_id和course_id两个外键,enrollments 的主键设置有两个选择:
- 将这两个外键作为联合主键;
- 另外设置一个单独的主键 enrollment_id。
- 联合主键可以防止同一个学生重复注册同一门课程,因为主键(这里是联合主键)是唯一不可重复的,这可以防止一些不合理的数据输入。坏处是如果 enrollments 未来有新的子表,就需要复制两个字段(而不是 enrollment_id 这样的一个字段)作为外键,这也不一定是很大的麻烦,要根据数据量以及子表是否还有子表等情况来考虑,在一定情况下可能会造成不必要冗余和麻烦(相对于将 enrollment_id 一个字段作为主键来说)。
创建表之间关系和设置ID时,先考虑当下的情况。
外键约束
有外键时,需要设置约束以防止数据损坏/污染(不一致)。
右边 Foreign KeyOptions 可分别选择当父表里的主键被修改或删除(Update / Delete)时,子表里的外键如何反应,有三种选项:
- CASCADE: 瀑布/串联/级联,表示随着主键改变而改变,如主键某学生的student_id从1变成2,则改学生的所有注册课程记录的 student_id也会全部变为2(注意主键一般也最好是永远不要变的,这里讨论的是特殊情况)
- RESTRICT/NO ACTION: 等效,作用都是禁止更改或删除主键。如:对于有过注册记录的课程,除非先删除该课程的注册购买记录,不然不能在 courses表里删除该课程的信息。(另外注意:MySQL 里外键默认的 On Update 和 On Delete 的反应都是 NO ACTION)
- SET NULL: 就是当主键更改或删除时,使得相应的外键变为空,这样的子表记录就没有对应的主键和对应的父表记录了(no parent),被称为孤儿记录(orphan record),这是垃圾数据,让我们不知道是谁注册的课程或不知道注册的是什么课程,一般不用,只在极其特殊的情况可能有用.
- 通常对于 UPDATE, 设置为 CASCADE 级联,随之改变.
对于 DELETE,看情况而定,可能设置为 CASCADE 随之删除 也可能设置为 RESTRICT / NO ACTION 禁止删除。不要死板,永远按照业务/商业需求来选择,这也正是为什么之前强调“理解业务需求”是最重要的一步。比如我们课程注册记录里包含购买价格信息,则应该禁止删除,否则之后想查询某课或某时间段的收入情况就不能实现,相反如果只是个用户登录并设定一系列提醒的软件,可能用户允许用户注销并删除所有提醒就没什么大不了的,但万一,我们需要这些提醒记录来进行统计,则又该设置为禁止删除,总之一定要根据具体业务需求来(always check with the business)。
2. 标准化
正式建立数据库前我们先要检查并确定现在的设计是最优化的(optimal),关键是没有任何冗余或重复,简洁且便于修改和保持一致性。重复数据会占用更多空间并且使得增删查改的操作复杂化,比如,如果用户名在多处出现的话,一旦更改用户名就要到多处更改否则就会使得数据不一致,出现无效数据。
为了防止重复冗余,需要遵循数据库设计的7大规则或者说7大范式,每一条都是建立在你已经遵循了前一条的基础上。实际上,99%的数据库之需要遵循前3大范式就够了。
2.1 第一范式
第一范式要求一行中的每一个单元格都应该有单一值,且不能出现重复列。Each cell should have a single value and we cannot have repeated columns。
案例:courses 里的 tags 标签列就不符合第一范式。tags 列用逗号隔开多个标签,不是单一值。若将 tags 分割成多列,每个标签一列,问题是我们不知道到底有多少标签,每次出现新标签就要改动表结构,这样的设计很糟糕。这也正是范式1要求没有重复列的原因。因此将tags列单独拉出生成表。
2.2 链接表
建立courses和tags之间的联系,发现两者是多对多关系(MySQL里只有一对一和一对多,没有多对多),这说明两者的关系需要进一步细化,我们添加一个course_tags表来专门描述两者间的关系,记录每一对课程和标签的组合,这个中间表或者说链表(link table)同时是 courses 和 tags 的子表,与这两个父表均为一对多的关系,建立两条一对多连线后MySql自动给 course_tags表增加了两个外键course_id和tage_id(注意去掉自动添加的表前缀),两者构成 course_tags表的联合主键。
建立链表细化多对多关系,这是很常用的一种方法,有时链表只包含引用的两个外键,如course_tags 表,有时链表还包含其它信息,如 enrollments 表。
链表也可以直接用多对多来生成。当表中存在不确定数值的属性列时需要在实体模型中进一步细分。
2.3 第二范式
每个表都应该是单一功能的/应该表示一个实体类型,这个表的所有字段都是用来描述这个实体的。Every table should describe one entity, and every column in that table should describe that entity。
以 courses 表为例,course_id、title、price 都完全是属于课程的属性,放在courses 表里没问题,但注册时间enrollment_date放在courses表里就不合适,因为一个课程可以被多个学生注册所以有多个注册时间,同样的注册时间也不应该是students表的属性,因为一个学生可以注册多门课所以可以有多个注册时间,注册时间应该是属于“注册事件”的属性,所以应该另外建个enrollments表,放在该表里。
总之,第一范式是要求单一值和无重复列,这里第二范式是要求表中所有列都只能是完全描述该表所代表的实体的属性,不属于该实体(如订单表)的、在记录中可重复的属性,应该另外放在描述相应实体的表里(如顾客表)。
案例:courses里的instructors虽然是单一值符合第一范式却不符合第二范式,因为老师不是完全属于课程的属性,老师在不同课程中可能重复。所以,另外建立instructrors表作为父表,包含instructor_id和name字段,其中instructor_id为主键,一对多连接courses表后自动引进courses表作为外键,删除原先的instructor列。还有注意设置外键约束,UPDATE 设置为CASCADE,DELETE设置为NO ACTION,也就是instructor_id会随着instructors表更改,但不允许在某教师有课程的情况下删除该教师的信息。
2.4 第三范式
一个表中的字段不应该是由表中其他字段推导而来。A column in a table should not be derived from other columns.
案例:
- invoices 发票表里假设有三个字段:发票额、支付额 和 余额,第三个可以由前两个相减得到所以不符合3NF,每次前两者更新第三个就要随之更新,假设没有这样做,让三者出现了 100,40,80 这样不一致的数据,就不知道到底该相信哪个了,余额到底是 80 还是 100-40=60?
- 如果表里已经有 first_name 和 last_name 就不该有 full_name,因为第三者总是可以由前两者合并得到不管是上面的 余额balance 还是 全名fullname,都是一种冗余,应该删除。
这些范式目的:减少数据重复和冗余,增强数据的一致性和完整性。
3. 数据库模型修改
3.1 模型的正向工程
通过模型正向搭建数据库:workbench 菜单的 Database 选项 → Forward Engineer 正向搭建数据库。依据向导保持默认不断点下一步就好了,不要更改,除非你知道你在做什么。
最后一步会展示对应的SQL代码,里面有创建 school 数据库(schema 架构;模式;纲目;结构方案)以及各表的SQL代码,之后会详细讲。可以选择保存代码为文件(以保存到仓库中)或者复制到剪贴板然后到workbench查询窗口里以脚本方式运行,这里我们直接运行,返回local instance连接刷新界面就可以看到新的school数据库和里面的6张表了。
3.2 同步数据库模型
之后可能会修改数据库结构,比如更改某些表中字段的数据类型或增加字段之类,如果只是自己一个人用的一个本地数据库,可以直接打开对应表的设计模式并点击更改即可,但如果是在团队中工作通常不是这样。在中大型团队中,我们通常有多个服务器来模拟各种环境,其中有:
- 生产环境production environment:用户真正访问应用和数据库的地方;
- 模拟环境staging environment:与生产环境十分接近;
- 测试环境testing environment:存粹用来做测试的
- 开发环境development environment
每次需要对数据库做修改时我们需要复制相同的修改到不同的环境以保持数据的一致性。
***操作:***所以不能是在设计模式中直接点击修改,相反,是在之前模型标签(注意模型可以保存为一个 MySQL 模型文件,下次可以直接打开使用)里的实体模型图(EER Diagram)中修改表或字段,并使用菜单中的 Database →Synchronize Model ( 用 模 型 创 建 数 据 库 时 用 Forward Engineer , 对 已 有 数 据 库 进 行 同 步 修 改 时 用Synchronize Model ) 。 注 意 点 开 Synchronize Model 后 可 以 选 择 连 接 。
3.3 模型的逆向工程
为数据库创建模型,之后可以在模型上更改,便于同步各个环境下的数据库数据。
模型图中实线和虚线表示强联系和弱联系,实线表示must be,虚线表示may be。
Note:
- 关闭当前 Model,不然之后的逆向工程结果会添加到当前模型上,最好是每个数据库都有一个单独的模型,除非数据库间相互关联否者不要在一个模型中处理多个数据库.
- Database → Reverse Engineer,可以选择目标数据库,如上说所,除非数据库相互关联,否者最好一次只逆向工程一个数据库,让每个数据库都有一个单独的模型.
- 可以对逆向的表格进行筛选。
在反向搭建出的模型中,可以更好的看到和理解数据库的结构设计,可以修改表结构(并将相关修改脚本保存并用于其它环境的数据库),还可以发现问题。尽量消除没有关联的表格。
3.4 实际应用建议
- 不要死记范式规则,重点在于消除冗余,减轻数据库复杂度
比如发现一个name字段下出现的是一些重复的名字而不是重复的外键(如某种id),那就说明设计还不够归一化,具体违反哪条范式并不重要,关键是专注于避免重复性。 - 不要对什么都建模
简单才是最高境界。Simplicity is the Ultimate Sophistication. - 第六范式:不要在关系型数据库中再建关系型数据结构。
设计数据库时总是考虑当前的业务需求,不要试图包罗万象,总有开发人员会考虑各种未来可能出现的需求,实际上大部分那些需求都从未发生,反而使得数据库增加了很多没必要的复杂性,复杂化了查询并拖慢了执行效率.
建立复杂模型不是本事,让模型尽可能优美简单易懂又能满足目前的需求这才是本事,如果还能有不错的拓展性以满足未来可能的新特性就更好了.
尽可能保持简洁,简洁才是终极哲学,无论你对未来的预测有多好,总会有意料之外的需求出现,总有一天你会写脚本改数据库甚至进行数据迁移,这是避免不了的,当前只需考虑如何最好地满足目前的需求就好了,不要企图对全宇宙建模。
4. 数据库实体模型
4.1 创建和删除数据库
用workbench的向导来创建和修改数据库能够提高效率,但作为 DBA (Database Administrator 数据库管理员),你必须要能理解并审核相关代码,确保其不会对数据库有不利影响,而且也有能力手动写代码完成创建和修改数据库的操作,可以不依赖(图形化和向导)工具。
创建和删除数据库代码:
CREATE DATABASE IF NOT EXISTS sql_store2;
DROP DATABASE IF EXISTS sql_store2;
4.2 创建表
DROP DATABASE IF EXISTS sql_store2;
CREATE DATABASE IF NOT EXISTS sql_store2;
-- 没有就创建,有就删除
USE sql_store2; -- 创建数据库后一定要选择相关数据库
DROP TABLE IF EXISTS customers;
CREATE TABLE IF NOT EXISTS customers(customer_id INT PRIMARY KEY AUTO_INCREMENT,first_name VARCHAR(50) NOT NULL,points INT NOT NULL DEFAULT 0,email VARCHAR(255) NOT NULL UNIQUE
);
NOTE:
- 创建对象(不管是数据库还是表)有两种方式,DROP …… IF EXIXTS ……; CREAT …… 和 CREAT …… IF NOT EXISTS ……,注意两种方式的区别在于,当原对象存在时,前者是推倒重建,后者是保持原状放弃创建(所以按通常的需求来看还是前者更符合)。
- 括号中设置列的方式为 列名 数据类型 各种列性质,列间逗号分隔,常用的列性质有PRIMARY KEY 、AUTO_INCREMENT、 NOT NULL 、DEFAULT 0、 UNIQUE。
4.3 更改表
ALTER TABLE customersADD COLUMN last_name VARCHAR(50) NOT NULL AFTER first_name,ADD city VARCHAR(50) NOT NULL,MODIFY COLUMN first_name VARCHAR(60) DEFAULT '',
DROP COLUMN points;
NOTE:
- COLUMN 是可选的,有的人喜欢加上以增加可读性;
- AFTER first_name 是可选的,不加的话默认将新列添加到最后一列;
- MODIFY 修改已有列,经实验发现其实应该是重置该列(= DROP + ADD),所以注意要列出全部类型和属性信息,如上例中将 first_name 修改为 VARCHAR(60) 类型并将默认值修改为空字符串’',但忘了加 NOT NULL,刷新后发现 first_name 不再有 NOT NULL 属性;
- 列名最好不要有空格,但如果有的话可用反引号包裹,如
last name
. - 修改表永远不要直接在生产环境中进行,要首先在测试环境进行,确保没有错误和不良影响后再到生产环境进行修改。
4.4 创建关系
CREATE DATABASE IF NOT EXISTS sql_store2;
USE sql_store2;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS customers;
CREATE TABLE customers(customer_id INT PRIMARY KEY AUTO_INCREMENT,first_name VARCHAR(50) NOT NULL,points INT NOT NULL DEFAULT 0,email VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE orders(order_id INT PRIMARY KEY,customer_id INT NOT NULL,order_date DATE NOT NULL, -- 在添加完所有的列之后设置外键FOREIGN KEY fk_orders_customers(customer_id)REFERENCES customers(customer_id)ON UPDATE CASCADEON DELETE NO ACTION
);
Note:
- 外键名的命名习惯:fk_子表_父表
- 语法结构:
FOREIGN KEY 外键名 (外键字段)
REFERENCES 父表 (主键字段)
-- 【设置外键约束】
ON UPDATE CASCADE
ON DELETE NO ACTION
- 应该把orders表(子表)的DROP语句放到最前面,不然第二次运行会出问题。
4.5 更改主键和外键约束
USE sql_store2;
ALTER TABLE ordersDROP PRIMARY KEY,ADD PRIMARY KEY (order_id),DROP FOREIGN KEY fk_orders_customers,ADD FOREIGN KEY fk_orders_customers (customer_id)references customers (customer_id)ON UPDATE CASCADEON DELETE NO ACTION;
Note:
- 这里不管是之前创建orders表时设置外键还是这里通过修改ADD增加外键,外键名明明写的是 fk_orders_customers,实际上都会变成 orders_ibfk_1,要去设计模式手动修改才行,可能是bug
- 通过类似的 ALTER TABLE 语句增删主键:可增加多个主键,在括号内用逗号隔开,注意说的是 ADD 其实是重置,所以一次要把该表所有需要的主键声明完整。
4.6 字符集和排序规则
字符是以数字序列的形式储存于电脑中的,字符集是数字序列与字符相互转换的字典,不同的字符集支持不同的字符范围,有些支持拉美语言字符,有些也支持亚洲语言字符,有些支持全世界所有字符,查看MySQL支持的所有字符集:
SHOW CHARSET;
其中armscii8支持亚美尼亚语,big5支持繁体中文,gb2312和gbk支持简体中文(gk是国标的拼音简称,k是扩展的拼音简称),而utf-8支持全世界的语言,utf-8也是MySQL自版本5之后的默认字符集。还可以看到字符集描述,默认排序规则,最大长度。
排序规则(collation)指的是某语言内字符的排序方式,utf-8的默认排序规则是utf8_general_ci,其中ci表示case insensitive大小写不敏感,即MySQL在排序时不会区分大小写,这在大部分时候都是适用的,比如用户输入名字的时候大小写不固定,我们希望只按照字符顺序而不管大小写来对名字进行排序。总之,99.9%的情况下都不需要更改默认排序规则。
对于字符集来说,大部分时候用默认的utf-8就行了。但有时,我们可以通过更改字符集来减少空间占用,例如,我们某个特定的应用(对应的数据库)/特定表/特定列是只能输入英文字符的,那如果将该列的字符集从utf-8改为latin1,占用空间就会缩小到原来的1/3,以字段类型为CHAR(10)(固定预留10个字符)且有1百万条记录为例,占用空间就会从约30MB减到10MB。接下来将如何用菜单和代码方式更改库/表/列的字符集。
-
Workbench更改办法
- 菜单方式更改字符集:右键sql_store2 数据库,点击 Schema Inspector可查看;
- 要修改库或者表和列的字符集,直接点开库或者表的设计模式(扳手按钮)在里面选择更改即可。
-
代码更改
1)在创建数据库时设置字符集或更改已有数据库字符集
CREATE/ALTER DATABASE db_name
CHARACTER SET latin1
2)在创建表时设置字符集或更改已有表的字符集
CREATE/ALTER TABLE table1
(……)
CHARACTER SET latin1
3)在创建表时设置列的字符集
CREATE TABLE IF NOT EXISTS customers(
customer_id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50) CHARACTER SET latin1 NOT NULL,
points INT NOT NULL DEFAULT 0,
email VARCHAR(255) NOT NULL UNIQUE)
4.7 存储引擎
在MySQL中我们有若干种储存引擎,储存引擎决定了我们数据的储存方式以及可用的功能.
SHOW ENGINES;
储存引擎有很多,我们真正需要知道只有两个:MyISAM(读作 My-I-SAM) 和 InnoDBMyISAM是曾经很流行的引擎,但自MySQL5.5之后,默认引擎就改为InnoDB了,InnoDB支持更多的功能特性,包括事务、外键等等,所以最好使用InnoDB引擎是表层级的设置,每个表都可以设置不同的引擎(虽然这没必要)。
外键是十分重要的,它可以增加引用一致性/完整性(referential integrity),如果我们有一个老数据库的引擎是 MyISAM,我们想要给它设置外键,就必须要将其引擎升级为 InnoDB,可以在表的设计模式里选择更改,也可以用修改表的代码:
ALTER TABLE customers
ENGINE = InnoDB;
改变引擎是一个代价极高(expensive)的操作,它会重建整个表,在此期间无法方法访问数据。所以,不要轻易在生产环境中改变储存引擎,除非有特殊的理由。
相关文章:

MySQL:设计数据库与操作
设计数据库 1. 数据建模1.1 概念模型1.2 逻辑模型1.3 实体模型主键外键外键约束 2. 标准化2.1 第一范式2.2 链接表2.3 第二范式2.4 第三范式 3. 数据库模型修改3.1 模型的正向工程3.2 同步数据库模型3.3 模型的逆向工程3.4 实际应用建议 4. 数据库实体模型4.1 创建和删除数据库…...

OBS 免费的录屏软件
一、下载 obs 【OBS】OBS Studio 的安装、参数设置和录屏、摄像头使用教程-CSDN博客 二、使用 obs & 输出无黑屏 【OBS任意指定区域录屏的方法-哔哩哔哩】 https://b23.tv/aM0hj8A OBS任意指定区域录屏的方法_哔哩哔哩_bilibili 步骤: 1)获取区域…...

uniapp微信小程序使用xr加载模型
1.在根目录与pages同级创建如下目录结构和文件: // index.js Component({properties: {modelPath: { // vue页面传过来的模型type: String,value: }},data: {},methods: {} }) { // index.json"component": true,"renderer": "xr-frame&q…...
机器人运动范围检测 c++
地上有一个m行n列的方格,一个机器人从坐标(0,0)的格子开始移动,它每次可以向上下左右移动一个格子,但不能进入行坐标和列坐标的位数之和大于k的格子,请问机器人能够到达多少个格子 #include &l…...

kettle从入门到精通 第七十四课 ETL之kettle kettle调用https接口教程,忽略SSL校验
场景:kettle调用https接口,跳过校验SSL。(有些公司内部系统之间的https的接口是没有SSL校验这一说,无需使用用证书的) 解决方案:自定义插件或者自定义jar包通过javascript调用https接口。 1、http post 步…...
C++轻量级 线程间异步消息架构(向曾经工作的ROSA-RB以及共事的DOPRA的老兄弟们致敬)
1 啰嗦一番背景 这么多年,换着槽位做牛做马,没有什么钱途 手艺仍然很潮,唯有对于第一线的码农工作,孜孜不倦,其实没有啥进步,就是在不断地重复,刷熟练度,和同期的老兄弟们…...
Kotlin中的类
类初始化顺序 constructor 里的参数列表是首先被执行的,紧接着是 init 块和属性初始化器,最后是次构造函数的函数体。 主构造函数参数列表firstProperty 初始化第一个 init 块secondProperty 初始化第二个 init 块次构造函数函数体 class Example const…...
VSCode中常用的快捷键
通用操作快捷键 显示命令面板:Ctrl Shift P or F1,用于快速访问VSCode的各种命令。 快速打开:Ctrl P,可以快速打开文件、跳转到某个行号或搜索项目内容。 新建窗口/实例:Ctrl Shift N,用于打开一个新的…...

代码随想录-Day45
198. 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个…...

Rust Eq 和 PartialEq
Eq 和 PartialEq 在 Rust 中,想要重载操作符,你就需要实现对应的特征。 例如 <、<、> 和 > 需要实现 PartialOrd 特征: use std::fmt::Display;struct Pair<T> {x: T,y: T, }impl<T> Pair<T> {fn new(x: T, y: T) ->…...

思考如何学习一门编程语言?
一、什么是编程语言 编程语言是一种用于编写计算机程序的人工语言。通过编程语言,程序员可以向计算机发出指令,控制计算机执行各种任务和操作。编程语言由一组语法规则和语义规则组成,这些规则定义了如何编写代码以及代码的含义。 编程语言…...

顺序串算法库构建
学习贺利坚老师顺序串算法库 数据结构之自建算法库——顺序串_创建顺序串s1,创建顺序串s2-CSDN博客 本人详细解析博客 串的概念及操作_串的基本操作-CSDN博客 版本更新日志 V1.0: 在贺利坚老师算法库指导下, 结合本人详细解析博客思路基础上,进行测试, 加入异常弹出信息 v1.0补…...

[论文阅读笔记33] Matching Anything by Segmenting Anything (CVPR2024 highlight)
这篇文章借助SAM模型强大的泛化性,在任意域上进行任意的多目标跟踪,而无需任何额外的标注。 其核心思想就是在训练的过程中,利用strong augmentation对一张图片进行变换,然后用SAM分割出其中的对象,因此可以找到一组图…...

阿里Nacos下载、安装(保姆篇)
文章目录 Nacos下载版本选择Nacos安装Windows常见问题解决 更多相关内容可查看 Nacos下载 Nacos官方下载地址:https://github.com/alibaba/nacos/releases 码云拉取(如果国外较慢或者拉取超时可以试一下国内地址) //国外 git clone https:…...
四、golang基础之defer
文章目录 一、定义二、作用三、结果四、recover错误拦截 一、定义 defer语句被用于预定对一个函数的调用。可以把这类被defer语句调用的函数称为延迟函数。 二、作用 释放占用的资源捕捉处理异常输出日志 三、结果 如果一个函数中有多个defer语句,它们会以LIFO…...
机器人----四元素
四元素 四元素的大小 [-1,1] 欧拉角转四元素...
IBM Spectrum LSF Application Center 提供单一界面来管理应用程序、用户、资源和数据
IBM Spectrum LSF Application Center 提供单一界面来管理应用程序、用户、资源和数据 亮点 ● 简化应用程序管理 ● 提高您的工作效率 ● 降低资源管理的复杂性 ● 深入了解流程 IBM Spectrum LSF Application Center 为集群用户和管理员提供了一个灵活的、以应用为中心的界…...

如何选择品牌推广公司?哪家好?收费标准及评价!
不管是什么品牌,推广对公司的成败起了很关键的作用。然而,面对市面上琳琅满目的品牌推广公司,如何选择一家既熟悉又靠谱的公司,成为许多企业主面临的难题。 作为一家手工酸奶品牌的创始人,目前全国也复制了100多家门店…...

JDeveloper 12C 官网下载教程
首先、我们要登录Oracle官网 Oracle 甲骨文中国 | 云应用和云平台 登录进去如果不是中文可以点击右上角带有国旗的图标就行更改,选择一个你能看懂的文字。 然后,点击“资源”—点击“开发人员下载” 然后,点击“开发工具” 这里有很多工具可…...
中英双语介绍美国的州:印第安纳州(Indiana)
中文版 印第安纳州简介 印第安纳州位于美国中西部地区,是一个以其农业、制造业和体育文化而著称的州。以下是对印第安纳州的详细介绍,包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 印第安纳州东临俄亥俄州,北接密歇根州…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...