周五满课的一天,没什么好说的,上午政治课上复习写译。
下午正常上课。
晚上出门买了CoCo联名鸣潮。
然后开始干活:
1道简单,1道中等。
- 字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
string multiply(string num1, string num2) {
if (num1 == "0" || num2 == "0")
return "0";
int n1=num1.size();
int n2=num2.size();
vector<vector<int>> num;
reverse(num1.begin(),num1.end());
reverse(num2.begin(),num2.end());
num.resize(n1);
for(int i=0;i<n1;i++)
{
int x=num1[i]-'0';
int sign = 0;//for里面要保留sign,在这边要重置。
for(int j=0;j<n2;j++)
{
int y=num2[j]-'0';
int temp=x*y+sign;
int z=temp%10;
sign=temp/10;
num[i].push_back(z);
}
// 处理当前行乘法的剩余进位,x*y+sign可能是100多
if(sign > 0) {
num[i].push_back(sign);
}
for(int a=0;a<i;a++)//从第一位起,到后面,十位要在前面补0
{
num[i].insert(num[i].begin(),0);
}
}
int n=num[n1-1].size();
int sum;
int carry=0;
string ans="";
for(int j=0;j<n;j++)
{
sum=0;
for(int i=0;i<n1;i++)//每一列的数字进行相加
{
int b=0;
if(j<num[i].size())
{
b=num[i][j];
}
sum=sum+b;
}
sum=sum+carry;
char ch=sum%10+'0';
carry=sum/10;
ans=ans+ch;
}
if(carry)
{
char ch1=carry+'0';
ans=ans+ch1;
}
reverse(ans.begin(),ans.end());
return ans;
}
虽然写的是中等,但好多细节,我觉得可以给到困难了,一个是字符串相加,还有就是字符串相乘。
相加前面一题还练过,还知道要处理最后一位有进位要补进位。
但是字符串相乘也要补进位;
然后是看数据库。
索引一块搞完了,SQL优化开了个头。
设计原则
- 针对于数据量较大,且查询比较频繁的表建立索引
- 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引
- 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高
- 如果是字符串类型的字段,字段长度较长,可以针对于字段的特点,建立前缀索引
- 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率
- 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价就越大,会影响增删改的效率
- 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询
SQL优化
插入数据
普通插入:
- 采用批量插入(一次插入的数据不建议超过1000条)
- 手动提交事务
- 主键顺序插入
本地大量插入数据:
# 客户端连接服务端时,加上参数 --local-infile(这一行在bash/cmd界面输入)
mysql --local-infile -u root -p
# 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;
select @@local_infile;
# 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/load_user_100w_sort.sql' into table tb_user fields terminated by ',' lines terminated by '\n';
主键优化
页分裂:页可以为空,也可以填充一般,也可以填充100%,每个页包含了2-N行数据(如果一行数据过大,会行溢出),根据主键排列。
顺序插入,没有页分裂:

image.png
页分裂:

image.png
页合并:当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。
当页中删除的记录到达 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前后)看看是否可以将这两个页合并以优化空间使用。

image.png
主键设计原则:
● 满足业务需求的情况下,尽量降低主键的长度
二级索引下挂的是主键索引,主键索引短一些,其他的二级索引的占用也小一点
● 插入数据时,尽量选择顺序插入,选择使用 AUTO_INCREMENT 自增主键
● 尽量不要使用 UUID 做主键或者是其他的自然主键,如身份证号
● 业务操作时,避免对主键的修改