[转]Mysql数据库开发的36条原则

前言

这些原则都是经历过实战总结而成

每一条原则背后都是血淋淋的教训

这些原则主要是针对数据库开发人员,在开发过程中务必注意

总是在灾难发生后,才想起容灾的重要性;

总是在吃过亏以后,才记得曾有人提醒过。

 

 

一、核心原则

1.尽量不在数据库做运算

俗话说:别让脚趾头想事情,那是脑瓜子的职责

作为数据库开发人员,我们应该让数据库多做她所擅长的事情:

  • 尽量不在数据库做运算

  • 复杂运算移到程序端CPU

  • 尽可能简单应用MYSQL

举例:

在mysql中尽量不要使用如:md5()、Order by Rand()等这类运算函数

2.尽量控制单表数据量

大家都知道单表数据量过大后会影响数据查询效率,严重情况下会导致整个库都卡住

一般情况下,按照一年内单表数据量预估:

  • 纯INT不超过1000W

  • 含CHAR不超过500W

同时要尽量做好合理的分表,使单表数据量不超载,常见的分表策略有:

  • 通过USERID来分表(根据ID区间分表):在金融行业应用较多,用户量大、用户特征明显

  • 按DATE分表(按天、周、月分表):在电信行业应用非常多,如用户上网记录表、用户短信表、话单表等

  • 按AREA分表(省、市、区分表)

  • 其他

分区表的适用场景主要有:

① 表非常大,无法全部存在内存,或者只在表的最后有热点数据,其他都是历史数据;

② 分区表的数据更易维护,可以对独立的分区进行独立的操作;

③ 分区表的数据可以分布在不同的机器上,从而高效使用资源;

④ 可以使用分区表来避免某些特殊的瓶颈;

⑤ 可以备份和恢复独立的分区。

但是使用分区表同样有一些限制,在使用的时候需要注意:

① 一个表最多只能有 1024 个分区;

② 5.1版本中,分区表表达式必须是整数, 5.5可以使用列分区;

③ 分区字段中如果有主键和唯一索引列,那么主键列和唯一列都必须包含进来;

④ 分区表中无法使用外键约束;

⑤ 需要对现有表的结构进行修改;

⑥ 所有分区都必须使用相同的存储引擎;

⑦ 分区函数中可以使用的函数和表达式会有一些限制;

⑧ 某些存储引擎不支持分区;

⑨ 对于 MyISAM 的分区表,不能使用 load index into cache;

⑩ 对于 MyISAM 表,使用分区表时需要打开更多的文件描述符。

3.尽量控制表字段数量

单表的字段数量也不能太多,根据业务场景进行优化调整,尽量调整表字段数少而精,这样有以下好处:

  • IO高效

  • 全表遍历

  • 表修复快

  • 提高并发

  • alter table更快

那究竟单表多少字段合适呢?

按照单表1G体积,500W行数据量进行评估:

  • 顺序读1G文件需N秒

  • 单行不超过200Byte

  • 单表不超50个纯INT字段

  • 单表不超20个CHAR(10)字段

==>建议单表字段数上限控制在20~50个

4.平衡范式与冗余

 

数据库表结构的设计也讲究平衡,以往我们经常说要严格遵循三大范式,所以先来说说什么是范式:

第一范式:单个字段不可再分。唯一性。 

第二范式:不存在非主属性只依赖部分主键。消除不完全依赖。 

第三范式:消除传递依赖。

用一句话来总结范式和冗余:

冗余是以存储换取性能,

范式是以性能换取存储。

所以,一般在实际工作中冗余更受欢迎一些。

模型设计时,这两方面的具体的权衡,首先要以企业提供的计算能力和存储资源为基础。

其次,一般互联网行业中都根据Kimball模式实施数据仓库,建模也是以任务驱动的,因此冗余和范式的权衡符合任务需要。

例如,一份指标数据,必须在早上8点之前处理完成,但计算的时间窗口又很小,要尽可能减少指标的计算耗时,这时在计算过程中要尽可能减少多表关联,模型设计时需要做更多的冗余。

5.拒绝3B

数据库的并发就像城市交通,呈非线性增长

 

这就要求我们在做数据库开发的时候一定要注意高并发下的瓶颈,防止因高并发造成数据库瘫痪。

这里的拒绝3B是指:

  • 大SQL(BIG SQL):要减少

  • 大事务(BIG Transaction)

  • 大批量(BIG Batch)

二、字段类原则

1.用好数值字段类型

三类数值类型:

  • 整型:TINYINT(1Byte)、TINYINT(1Byte)、SMALLINT(2B)、MEDIUMINT(3B)、INT(4B)、BIGINT(8B)

  • 浮点型:FLOAT(4B)、DOUBLE(8B)

  • DECIMAL(M,D)

以几个常见的例子来进行说明:

1)INT(1) VS INT(11)

很多人都分不清INT(1)和INT(11)的区别,想必大家也很好奇吧,其实1和11其实只是显示长度的却别而已,也就是不管int(x)x的值是什么值,存储数字的取值范围还是int本身数据类型的取值范围,x只是数据显示的长度而已。

2)BIGINT AUTO_INCREMENT

大家都知道,有符号int最大可以支持到约22亿,远远大于我们的需求和MySQL单表所能支持的性能上限。对于OLTP应用来说,单表的规模一般要保持在千万级别,不会达到22亿上限。如果要加大预留量,可以把主键改为改为无符号int,上限为42亿,这个预留量已经是非常的充足了。

使用bigint,会占用更大的磁盘和内存空间,内存空间毕竟有限,无效的占用会导致更多的数据换入换出,额外增加了IO的压力,对性能是不利的。

因此推荐自增主键使用int unsigned类型,但不建议使用bigint。

3)DECIMAL(N,0)

当采用DECIMAL数据类型的时候,一般小数位数不会是0,如果小数位数设置为0,那建议使用INT类型

2.将字符转化为数字

数字型VS字符串型索引有更多优势:

  • 更高效

  • 查询更快

  • 占用空间更小

举例:用无符号INT存储IP,而非CHAR(15)

INT UNSIGNED

可以用INET_ATON()和INET_NTOA()来实现IP字符串和数值之间的转换

3.优先使用ENUM或SET

对于一些枚举型数据,我们推荐优先使用ENUM或SET,这样的场景适合:

1)字符串型

2)可能值已知且有限

存储方面:

1)ENUM占用1字节,转为数值运算

2)SET视节点定,最多占用8字节

3)比较时需要加‘单引号(即使是数值)

举例:

`sex` enum('F','M')  COMMENT '性别';

`c1` enum('0','1','2','3') COMMENT '审核';

4.避免使用NULL字段

为什么在数据库表字段设计的时候尽量都加上NOT NULL DEFAULT '',这里面不得不说用NULL字段的弊端:

  • 很难进行查询优化

  • NULL列加索引,需要额外空间

  • 含NULL复合索引无效

举例:

1)`a`  char(32)  DEFAULT NULL  【不推荐】

2)`b`  int(10) NOT NULL  【不推荐】

3)`c`  int(10) NOT NULL DEFAULT 0  【推荐】

5.少用并拆分TEXT/BLOB

TEXT类型处理性能远低于VARCHAR

  • 强制生成硬盘临时表

  • 浪费更多空间

  • VARCHAR(65535)==>64K(注意UTF-8)

尽量不用TEXT/BLOB数据类型

如果业务需要必须用,建议拆分到单独的表

举例:


CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT,data TEXT NOT NULL,PRIMARY KEY(id)
) ENGINE=InnoDB;

 

6.不在数据库里存图片

先上图:

可见,如果将图片全部存在数据库,将使得数据库体积变大,会造成读写速度变慢。

图片存数据库的弊端:

  • 对数据库的读/写的速度永远都赶不上文件系统处理的速度

  • 数据库备份变的巨大,越来越耗时间

  • 对文件的访问需要穿越你的应用层和数据库层

★推荐处理办法:数据库中保存图片路径

按照年月日生成路径。具体是按照年月日还是按照年月去生成路径,根据自己需要(不一定是按照日期去生成)。

理解为什么要分散到多个文件夹中去才是关键,涉及到一个原理就明白了:

操作系统对单个目录的文件数量是有限制的。当文件数量很多的时候。从目录中获取文件的速度就会越来越慢。所以为了保持速度,才要按照固定规则去分散到多个目录中去。

图片分散到磁盘路径中去。数据库字段中保存的是类似于这样子的”images/2012/09/25/ 1343287394783.jpg”

原来上传的图片文件名称会重新命名保存,比如按照时间戳来生成,1343287394783. jpg。这样子是为了避免文件名重复,多个人往同一个目录上传图片的时候会出现。

反正用什么样的规则命名图片,只要做到图片名称的唯一性即可。

比如网站的并发访问量大,目录的生成分得月细越好。比如精确到小时,一个小时都可以是一个文件夹。同时0.001秒有两个用户同时在上传图片(因为那么就会往同一个小时文件夹里面存图片)。因为时间戳是精确到秒的。为了做到图片名称唯一性而不至于覆盖,生成可以在在时间戳后面继续加毫秒微秒等。总结的规律是,并发访问量越大。就越精确就好了。

题外话:

1)为什么保存的磁盘路径,是”images/2012/09/25/1343287394783.jpg”,而不是” /images/2012/09/25/ 1343287394783.jpg”(最前面带有斜杠)

在页面中需要取出图片路径展示图片的时候,如果是相对路径,则可以使用”./”+”images/2012/09/25/1343287394783.jpg”进行组装。

如果需要单独的域名(比如做cdn加速的时候)域名,img1.xxx.com,img2.xxx.com这样的域名,

直接组装 “http://img1.xxx.com/”+”images/2012/09/25/1343287394783.jpg”

2)为什么保存的磁盘路径,是”images/2012/09/25/1343287394783.jpg”,而不是“http://www.xxx.com/images/2012/09/25/1343287394783.jpg"

这里其实涉及到CDN的知识,具体CDN的知识在此不多展开,简而言之:

cdn服务:对于静态内容是非常适合的。所以像商品图片,随着访问量大了后,租用cdn服务,只需要把图片上传到他们的服务器上去。

例子:北京访问长沙服务器,距离太远。我完全可以把商品图片,放到北京的云服务(我觉得现在提供给网站使用的云存储其实就是cdn,给网站提供分流和就近访问)上去。这样子北京用户访问的时候,实际上图片就是就近获取。不需要很长距离的传输。

自己用一个域名img.xxx.com来载入图片。这个域名解析到北京的云服务上去。

做法:数据库中保存的是” images/2012/09/25/1343287394783.jpg”,

这些图片实际上不存储在web服务器上。上传到北京的cdn服务器上去。

我从数据库取出来,直接”img.xxx.com/”+” images/2012/09/25/1343287394783.jpg”

比如如果还有多个,就命名img1.xx.com、img2.xx.com

反正可以随便。所以如果把域名直接保存进去。就显得很麻烦了。迁移麻烦。

三、索引类原则

1.谨慎合理添加索引

  • 添加索引是为了改善查询

  • 添加索引会减慢更新

  • 索引不是越多越好

  • 能不加的索引尽量不加(综合评估数据密度和数据分布,最好不超过字段数20%)

  • 结合核心SQL有限考虑覆盖索引

举例:不要给“性别”列创建索引

理论文章会告诉你值重复率高的字段不适合建索引。不要说性别字段只有两个值,网友亲测,一个字段使用拼音首字母做值,共有26种可能,加上索引后,百万加的数据量,使用索引的速度比不使用索引要慢!

为什么性别不适合建索引呢?因为你访问索引需要付出额外的IO开销,你从索引中拿到的只是地址,要想真正访问到数据还是要对表进行一次IO。假如你要从表的100万行数据中取几个数据,那么利用索引迅速定位,访问索引的这IO开销就非常值了。但如果你是从100万行数据中取50万行数据,就比如性别字段,那你相对需要访问50万次索引,再访问50万次表,加起来的开销并不会比直接对表进行一次完整扫描小。

2.字符字段必须建前缀索引

区分度:

  • 单字母区分度:26

  • 4字母区分度:26*26*26*26 = 456,976

  • 5字母区分度:26*26*26*26*26 = 11,881,376

  • 6字母区分度:26*26*26*26*26*26 = 308,915,776

字符字段必须建前缀索引,例如:

 
  1. `pinyin` varchar(100) DEFAULT NULL COMMENT '小区拼音',
  2. KEY `idx_pinyin` (`pinyin`(8)),
  3. ) ENGINE=InnoDB

3.不在索引列做运算

原因有两点:

1)会导致无法使用索引

2)会导致全表扫描

举例:

BAD SAMPLE:

 
  1. select * from table 
  2. WHERE to_days(current_date) – to_days(date_col) <= 10

GOOD SAMPLE: 

 
  1. select * from table 
  2. WHERE date_col >= DATE_SUB('2011-10-22',INTERVAL 10 DAY);

4.自增列或全局ID做INNODB主键

  • 对主键建立聚簇索引

  • 二级索引存储主键值

  • 主键不应更新修改

  • 按自增顺序插入值

  • 忌用字符串做主键

  • 聚簇索引分裂

  • 推荐用独立于业务的AUTO_INCREMENT列或全局ID生成器做代理主键

  • 若不指定主键,InnoDB会用唯一且非空值索引代替

5.尽量不用外键

线上OLTP系统尽量不用外键:

  • 外键可节省开发量

  • 有额外开销

  • 逐行操作

  • 可“到达”其他表,意味着锁

  • 高并发时容易死锁

建议由程序保证约束

比如我们原来建表语句是这样的:

 
  1. CREATE TABLE `user` (
  2. `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  3. `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
  4. PRIMARY KEY (`user_id`)
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  6. CREATE TABLE `order` (
  7. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  8. `total_price` decimal(10,2) NOT NULL DEFAULT '0.00',
  9. `user_id` int(11) NOT NULL DEFAULT '0',
  10. PRIMARY KEY (`id`),
  11. KEY `for_indx_user_id` (`user_id`),
  12. CONSTRAINT `for_indx_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

不使用外键约束后:

 
  1. CREATE TABLE `user` (
  2. `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  3. `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
  4. PRIMARY KEY (`user_id`)
  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  6. CREATE TABLE `order` (
  7. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  8. `total_price` decimal(10,2) NOT NULL DEFAULT '0.00',
  9. `user_id` int(11) NOT NULL DEFAULT '0',
  10. PRIMARY KEY (`id`)
  11. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

不适用外键约束后,为了加快查询我们通常会给不建立外键约束的字段添加一个索引。

 
  1. CREATE TABLE `order` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  3. `total_price` decimal(10,2) NOT NULL DEFAULT '0.00',
  4. `user_id` int(11) NOT NULL DEFAULT '0',
  5. PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`),
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

实际开发中,一般不会建立外键约束。

四、SQL类原则

1.SQL语句尽可能简单

在开发过程中,我们尽量要保持SQL语句的简单性,我们对比一下大SQL和多个简单SQL

  • 传统设计思想

  • BUG MySQL NOT

  • 一条SQL只能在一个CPU运算

  • 5000+ QPS的高并发中,1秒大SQL意味着?

  • 可能一条大SQL就把整个数据库堵死

拒绝大SQL,拆解成多条简单SQL

  • 简单SQL缓存命中率更高

  • 减少锁表时间,特别是MyISAM

  • 用上多CPU

2.保持事务(连接)短小

  • 事务/连接使用原则:即开即用,用完即关

  • 与事务无关操作都放到事务外面,减少锁资源的占用

  • 不破坏一致性前提下,使用多个短事务代替长事务

举例:

1)发帖时的图片上传等待

2)大量的sleep连接

3.尽可能避免使用SP/TRIG/FUNC

线上OLTP系统中,我们应当:

  • 尽可能少用存储过程

  • 尽可能少用触发器

  • 减少使用MySQL函数对结果进行处理

将上述这些事情都交给客户端程序负责

4.尽量不用SELECT *

用SELECT * 时,将会更多的消耗CPU、内存、IO以及网络带宽

我们在写查询语句时,应当尽量不用SELECT * ,只取需要的数据列:

  • 更安全的设计:减少表变化带来的影响

  • 为使用covering index提供可能性

  • Select/JOIN 减少硬盘临时表生成,特别是有TEXT/BLOB时

举例:

不推荐:

 
  1. SELECT * FROM tag
  2. WHERE id = 999148

推荐:

 
  1. SELECT keyword FROM tag
  2. WHERE id = 999148

5.改写OR为IN()

同一字段,将or改写为in()

OR效率:O(n)

IN效率:O(Log n)

当n很大时,OR会慢很多

注意控制IN的个数,建议n小于200

举例:

不推荐:

Select * from opp WHERE phone='12347856' or phone='42242233'

推荐:

Select * from opp WHERE phone in ('12347856' , '42242233')

6.改写OR为UNION

不同字段,将or改为union

  • 减少对不同字段进行 "or" 查询

  • Merge index往往很弱智

  • 如果有足够信心:set global optimizer_switch='index_merge=off';

举例:

不推荐:

 
  1. Select * from opp
  2. WHERE phone='010-88886666'
  3. or
  4. cellPhone='13800138000';

推荐:

 
  1. Select * from opp
  2. WHERE phone='010-88886666'
  3. union
  4. Select * from opp
  5. WHERE cellPhone='13800138000';

7.避免负向查询和%前缀模糊查询

在实际开发中,我们要尽量避免负向查询,那什么是负向查询呢,主要有以下:

NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE等

同时,我们还要避免%前缀模糊查询,因为这样会使用B+ Tree,同时会造成使用不了索引,并且会导致全表扫描,性能和效率可想而知

举例:

 

8.减少COUNT(*)

在开发中我们经常会使用COUNT(*),殊不知这种用法会造成大量的资源浪费,因为COUNT(*)资源开销大,所以我们能不用尽量少用

对于计数类统计,我们推荐:

  • 实时统计:用memcache,双向更新,凌晨跑基准

  • 非实时统计:尽量用单独统计表,定期重算

来对比一下COUNT(*)和其他几个COUNT吧:

 
  1. `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '公司的id',
  2. `sale_id` int(10) unsigned DEFAULT NULL,

结论:

COUNT(*)=COUNT(1)

COUNT(0)=COUNT(1)

COUNT(1)=COUNT(100)

COUNT(*)!=COUNT(col)

9.LIMIT高效分页

传统分页:

Select * from table limit 10000,10;

LIMIT原理:

  • Limit 10000,10

  • 偏移量越大则越慢

推荐分页:

 
  1. Select * from table WHERE id>=23423 limit 11;
  2. #10+1 (每页10条)
  3. select * from table WHERE id>=23434 limit 11;

分页方式二:

Select * from table WHERE id >= ( select id from table limit 10000,1 ) limit 10;

分页方式三:

SELECT * FROM table INNER JOIN (SELECT id FROM table LIMIT 10000,10) USING (id) ;

分页方式四:

 
  1. #先使用程序获取ID:
  2. select id from table limit 10000,10;
  3. #再用in获取ID对应的记录
  4. Select * from table WHERE id in (123,456…) ;

具体需要根据实际的场景分析并重组索引

示例:

10.用UNION ALL 而非UNION

如果无需对结果进行去重,仅仅是对多表进行联合查询并展示,则用UNION ALL,因为UNION有去重开销

举例:

 
  1. MySQL>SELECT * FROM detail20091128 UNION ALL
  2. SELECT * FROM detail20110427 UNION ALL
  3. SELECT * FROM detail20110426 UNION ALL
  4. SELECT * FROM detail20110425 UNION ALL
  5. SELECT * FROM detail20110424 UNION ALL
  6. SELECT * FROM detail20110423;

11.分解联接保证高并发

高并发DB不建议进行两个表以上的JOIN

适当分解联接保证高并发:

  • 可缓存大量早期数据

  • 使用了多个MyISAM表

  • 对大表的小ID IN()

  • 联接引用同一个表多次

举例:

原SQL:

 
  1. MySQL> Select * from tag
  2. JOIN tag_post
  3. on tag_post.tag_id=tag.id
  4. JOIN post
  5. on tag_post.post_id=post.id
  6. WHERE tag.tag=‘二手玩具’;

分解SQL:

 
  1. MySQL> Select * from tag WHERE tag=‘二手玩具’;
  2. MySQL> Select * from tag_post WHERE tag_id=1321;
  3. MySQL> Select * from post WHERE post.id in (123,456,314,141)

12.GROUP BY 去除排序

使用GROUP BY可以实现分组和自动排序

无需排序:Order by NULL

特定排序:Group by DESC/ASC

举例:

 

13.同数据类型的列值比较

原则:数字对数字,字符对字符

数值列与字符类型比较:同时转换为双精度进行比对

字符列与数值类型比较:字符列整列转数值,不会使用索引查询

举例:

字段:`remark` varchar(50) NOT NULL COMMENT '备注,默认为空',

 
  1. MySQL>SELECT `id`, `gift_code` FROM gift
  2. WHERE `deal_id` = 640 AND remark=115127;
  3. 1 row in set (0.14 sec)
  4. MySQL>SELECT `id`, `gift_code` FROM pool_gift
  5. WHERE `deal_id` = 640 AND remark='115127';
  6. 1 row in set (0.005 sec)

14.Load data 导数据

批量数据快导入:

  • 成批装载比单行装载更快,不需要每次刷新缓存

  • 无索引时装载比索引装载更快

  • Insert values ,values,values 减少索引刷新

  • Load data比insert快约20倍

尽量不用INSERT ... SELECT,一个是有延迟,另外就是会同步出错

15.打散大批量更新

  • 大批量更新尽量凌晨操作,避开高峰

  • 凌晨不限制

  • 白天上线默认为100条/秒(特殊再议)

举例:

 
  1. update post set tag=1 WHERE id in (1,2,3); 
  2. sleep 0.01; 
  3. update post set tag=1 WHERE id in (4,5,6); 
  4. sleep 0.01;
  5. ……

16.Know Every SQL

作为DBA乃至数据库开发人员,我们必须对数据库的每条SQL都非常了解,常见的命令有:

  • SHOW PROFILE

  • MYSQLsla

  • MySQLdumpslow

  • explain

  • Show Slow Log

  • Show Processlist

  • SHOW QUERY_RESPONSE_TIME(Percona)

五、约定类原则

1.隔离线上线下

构建数据库的生态环境,确保开发无线上库操作权限

原则:线上连线上,线下连线下

  • 生产数据用pro库

  • 预生产环境用pre库

  • 测试用test库

  • 开发用dev库

2.禁止未经DBA确认的子查询

  • 大部分情况优化较差

  • 特别WHERE中使用IN id的子查询

  • 一般可用JOIN改写

举例:

 
  1. MySQL> select * from table1 where id in (select id from table2)
  2. MySQL> insert into table1 (select * from table2)//可能导致复制异常

3.永远不在程序端显式加锁

  • 外部锁对数据库丌可控

  • 高幵发时是灾难

  • 极难调试和排查

对于类似并发扣款等一致性问题,我们采用事务来处理,Commit前进行二次校验冲突

4.统一字符集为UTF8

5.统一命名规范

1)库表等名称统一用小写

2)索引命名默认为“idx_字段名"

3)库名用缩写,尽量在2~7个字母

     DataSharing ==> ds

4)注意避免用保留字命名

以上所有坑,建议数据库开发人员都要铭记于心。

作者:真爱无敌


---------------------
作者:华为云
来源:CSDN
原文:https://blog.csdn.net/devcloud/article/details/100173405
版权声明:本文为作者原创文章,转载请附上博文链接!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kamp;R练习题6-1统计关键词出现的次数

这道练习题训练了&#xff1a; 1.结构体数组 2.二分查找 3.指针操作 ---- 都不难。但非常基础&#xff0c;我认为非常好&#xff0c;做完了记到博客上来&#xff0c;题目见k&R&#xff0c;实现例如以下&#xff1a; /** Practice of struct array. K&R 6-1* author : w…

大话领域驱动设计——表示层及其他

概述表示层又称用户界面层&#xff0c;包含应用程序的页面、组件等UI元素。服务层提供项目的HTTP API接口&#xff0c;包含MVC Controller和相关组件。ABP框架虽然在表示层提供了不少组件&#xff0c;但是这些和DDD本身没有多少关系。而且随着前后端分离架构的流行&#xff0c;…

C语言九十六之实现经典的字符串反转(通过指针或下标操作)

✅作者简介&#xff1a;大家好我是码莎拉蒂&#xff0c;CSDN博客专家&#x1f947;&#x1f947;&#x1f947; &#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;C语言试题200例 &#x1f4ac;推荐一款模拟面试、刷题神器&#x1f449; 点击跳转进…

Windows10家庭中文版没有本地策略选项完美解决方案

Win+R,在运行中输入:secpol.msc,查看安全设置是否打开,如下图所示。 组策略对于优化和维护Windows系统来说十分重要。众所周知,Windows 10家庭版中并不包含组策略,对于使用家庭版Windows的朋友来说,十分不方便。 通常情况下,如果策略组没有打开的话,在安装CAD等软件时…

JavaScript总结(六)

使用DOM操纵样式表 ✍ 操纵元素的Style样式属性&#xff08;所有的均对于CSS的内联式&#xff09; 对于每个CSS样式&#xff0c;Style对象都包含了一个相对应的属性&#xff0c;只需要用到style属性即可&#xff1b; Div.style.color "red"; //给div元素设置字体颜色…

[转]浅谈CMD和win powershell的区别

1、前言&#xff1a;本文给大家简单描述了一下POWERSHELL和CMD的区别&#xff0c;简单的说&#xff0c;Powershell是cmd的超集&#xff0c;换句话说&#xff0c;cmd能做的事情&#xff0c;Powershell都能做&#xff0c;但是Powershell还能额外做许多cmd不能做的活。 2、cmd是和…

【ArcGIS风暴】栅格计算器(Raster Calculator)运算出现错误问题及解决方案汇总

栅格计算器(Raster Calculator) 是一种空间分析函数工具,可以输入地图代数表达式,使用运算符和函数来做数学计算,建立选择查询,或键入地图代数语法。只有熟练的运用并记忆一些常用的公式,才能很好的运用栅格计算器。在使用的过程中,容易出现这样那样的问题,本文就把栅…

「博客之星」评选,互投5星,留链必投

⭐⭐ ⭐ ⭐⭐ 欢迎诚信互投⭐ ⭐ ⭐ ⭐⭐ ⭐⭐⭐⭐⭐ 谢谢各位大佬门&#xff0c;互投5星⭐⭐⭐⭐⭐ 投票地址&#xff1a; https://bbs.csdn.net/topics/603958492 投票地址&#xff1a; https://bbs.csdn.net/topics/603958492 投票地址&#xff1a; https://bbs.csdn.net…

为 ServiceCollection 实现装饰器模式

为 ServiceCollection 实现装饰器模式Intro在二十四种设计模式中&#xff0c;有一个模式叫做装饰器模式一般用来动态地给一个对象添加一些额外的职责&#xff0c;就增加功能来说&#xff0c;装饰模式比生成子类更为灵活&#xff0c;有更好的扩展性&#xff0c;我们也可以借助 D…

手把手教你启用Win10的Linux子系统 Ubuntu

1、打开“开发者选项” 2、启用“执行 Linux 程序的windows 子系统” 3、应用商店下载安装Ubuntu 附&#xff1a;ubuntu的一些命令及查看已安装软件包的命令 // 系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat…

jquery的height()和javascript的height总结,js获取屏幕高度

jquery的height()和javascript的height总结&#xff0c;js获取屏幕高度在javascript和jquery中&#xff0c;都有对各种高度的写法&#xff0c;在这里&#xff0c;我们就着重讲一下窗口、文档等高度的理解。(宽度和高度差不多&#xff01;)jquery的各种高度首先来说一说$(docume…

【地理信息系统GIS】教案(七章全)第五章:空间数据查询与空间分析

目录 第一节 空间数据查询第二节 缓冲区分析第三节 叠置分析第四节 网络分析第五节 DEM建立及分析第一节 空间数据查询 1.1 空间数据查询 1、空间数据查询的含义 从空间数据库中找出所有满足属性约束条件和空间约束条件的地理对象。 空间数据查询的一般过程 2、空间数据查询…

Understanding G1 GC Logs--转载

原文地址&#xff1a;https://blogs.oracle.com/poonam/entry/understanding_g1_gc_logs Understanding G1 GC Logs By Poonam-Oracle on Jun 18, 2012 The purpose of this post is to explain the meaning of GC logs generated with some tracing and diagnostic options fo…

Dart语言精简入门介绍

Dart语言精简入门介绍 1、介绍 Dart 在设计时应该是同时借鉴了 Java 和 JavaScript和kotlin 面向对象 JIT&AOT&#xff1a;JIT&#xff08;Just in Time&#xff09;优点&#xff1a;即时编译&#xff0c;开发期间更快编译&#xff0c;更快的重载&#xff1b;缺点&#…

WPF 窗口居中 变更触发机制

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;唐宋元明清原文地址&#xff1a;https://www.cnblogs.com/kybs0/p/7420767.html窗口居中 & 变更触发机制解决&#xff1a;1&#xff09;单实例窗口&#xff0c;窗口每次隐藏后再显示时…

[转]5分钟实现Android中更换头像功能

5分钟实现Android中更换头像功能 写在前面&#xff1a; 更换头像这个功能在用户界面几乎是100%出现的。通过拍摄照片或者调用图库中的图片&#xff0c;并且进行剪裁&#xff0c;来进行头像的设置。 功能相关截图如下&#xff1a; 下面我们直接看看完整吧&#xff1a; public cl…

Excel VBA窗体上打印系统时间print now出错原因及解决方案

如图所示,需要在窗体上显示当前系统时间: 首先,我们看一下now函数的原型: Now 函数   语法:Now   说明:返回一个 Variant (Date),根据计算机系统设置的日期和时间来指定日期和时间。   示例: Private Sub CommandButton1_Click()Dim a As Varianta = NowMsgBox…

(第九周)团队项目14

项目名&#xff1a;食物链教学工具 组名&#xff1a;奋斗吧兄弟 组长&#xff1a;黄兴 组员&#xff1a;李俞寰、杜桥、栾骄阳、王东涵 代码地址&#xff1a;HTTPS: https://git.coding.net/li_yuhuan/FoodChain.git SSH: gitgit.coding.net:li_yuhuan/FoodChain.git SCRUM会议…

为什么 C# 访问 null 字段会抛异常?

一&#xff1a;背景 1. 一个有趣的话题最近在看 硬件异常 相关知识&#xff0c;发现一个有意思的空引用异常问题&#xff0c;拿出来和大家分享一下&#xff0c;为了方便讲述&#xff0c;先上一段有问题的代码。namespace ConsoleApp2 {internal class Program{static Person pe…

Android项目实战(十五):自定义不可滑动的ListView和GridView

不可滑动的ListView (RecyclweView类似) public class NoScrollListView extends ListView {public NoScrollListView(Context context, AttributeSet attrs) {super(context,attrs);}public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ int mExpandSpec …