MySQL数据库基本指令(全)
数据库基本类型
CHAR 固定长度字符串 char(10) 存两位 占10位 查询有优势
VARCHAR 可变长度字符串 varchar(10) 存两位 占两位 存储有优势
枚举类型 只能取一个
set类型 能取多个
二进制类型 常用BLOB
一、避免创建数据库及表出现中文乱码和查看编码方法
#vim /etc/mysql/my.cnf 。(5.5以后系统)如下修改:
[client]
default-character-set=utf8
[mysqld]
default-storage-engine=INNODB
character-set-server=utf8
collation-server=utf8_general_ci
1、创建数据库的时候:
CREATE DATABASE `test`
CHARACTER SET 'utf8'
COLLATE 'utf8_general_ci';
2、建表的时候 CREATE TABLE `database_user` (
`ID` varchar(40) NOT NULL default '',
`UserID` varchar(40) NOT NULL default '',
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
代码练习数据:
create table `t_student` (
`id` double ,
`stuName` varchar (60),
`age` double ,
`sex` varchar (30),
`gradeName` varchar (60)
);
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('1','张三','23','男','一年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('2','张三丰','25','男','二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('3','李四','23','男','一年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('4','王五','22','男','三年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('5','珍妮','21','女','一年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('6','李娜','26','女','二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('7','王峰','20','男','三年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('8','梦娜','21','女','二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('9','小黑','22','男','一年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('10','追风','25','男','二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('11','小小张三','21',NULL,'二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('12','小张三','23','男','二年级');
insert into `t_student` (`id`, `stuName`, `age`, `sex`, `gradeName`) values('13','张三锋小','24',NULL,'二年级');
查询
单表查询
in 语句
SELECT * FROM t_student WHERE age in (21,23);
not in 语句
SELECT * FROM t_student WHERE age not in (21,23);
between and
SELECT * FROM t_student WHERE age BETWEEN 21 and 24;
not between and
SELECT * FROM t_student WHERE age not BETWEEN 21 and 24;
like 模糊查询
% 代表任意字符
_ 代表单个字符
SELECT * FROM t_student WHERE stuName LIKE '张%';
SELECT * FROM t_student WHERE stuName LIKE '张_';
SELECT * FROM t_student WHERE stuName LIKE '张__';(两个下划线代表两个字符)
空值查询
SELECT * FROM t_student WHERE sex IS NULL;
SELECT * FROM t_student WHERE sex IS NOT NULL;
带And的条件查询
SELECT * FROM t_student WHERE gradeName='一年级' AND age=23;
带or的条件查询
SELECT * FROM t_student WHERE age=21 or age=23;
distinct 去重复查询
SELECT DISTINCT gradeName FROM t_student;
对查询结果排序
SELECT * from t_student ORDER BY age DESC;(降序)
SELECT * from t_student ORDER BY age ASC;(升序)
group by 分组查询
group by 属性 [HAVING 条件表达式][WITH ROLLUP]
1.单独使用没有意义
SELECT * from t_student GROUP BY gradeName;
1 张三 23 男 一年级
4 王五 22 男 三年级
2 张三丰 25 男 二年级
2.与 GROUP_CONCAT()函数一起使用
GROUP_CONCAT()会计算哪些行属于同一组,将属于同一组的列显示出来。
要返回哪些列,由函数参数(就是字段名)决定。
分组必须有个标准,就是根据group by指定的列进行分组。
SELECT gradeName,GROUP_CONCAT(stuName) from t_student GROUP BY gradeName;
1 一年级 张三,小黑,李四,珍妮
7 三年级 王峰,王五
6 二年级 李娜,梦娜,张三丰,追风,小小张三,小张三,张三锋小
3.与聚合函数一起使用
1 一年级 4
4 三年级 2
2 二年级 7
4.与HAVING一起使用(限制输出的结果)
SELECT
id,
gradeName,
COUNT(stuName)
FROM
t_student
GROUP BY
gradeName
HAVING
COUNT(stuName) > 3;
1 一年级 4
2 二年级 7
5.与 with rollup 一起使用(最后加入一个总和行)
SELECT gradeName,COUNT(stuName) FROM t_student GROUP BY gradeName with ROLLUP
1 一年级 4
7 三年级 2
6 二年级 7
6 13
SELECT id,gradeName,GROUP_CONCAT(stuName) FROM t_student GROUP BY gradeName with ROLLUP
1 一年级 张三,小黑,李四,珍妮
7 三年级 王峰,王五
6 二年级 李娜,梦娜,张三丰,追风,小小张三,小张三,张三锋小
6 张三,小黑,李四,珍妮,王峰,王五,李娜,梦娜,张三丰,追风,小小张三,小张三,张三锋小
6. LIMIT 分页查询
select 字段1,字段2 from 表名 limit 初始位置,每页大小;
SELECT * from t_student LIMIT 0,5;
SELECT * from t_student LIMIT 5,5;
SELECT * from t_student LIMIT 10,5;
1 张三 23 男 一年级
2 张三丰 25 男 二年级
3 李四 23 男 一年级
4 王五 22 男 三年级
5 珍妮 21 女 一年级
6 李娜 26 女 二年级
7 王峰 20 男 三年级
8 梦娜 21 女 二年级
9 小黑 22 男 一年级
10 追风 25 男 二年级
11 小小张三 21 二年级
12 小张三 23 男 二年级
13 张三锋小 24 二年级
使用聚合函数查询
create table `t_grade` (
`id` int ,
`stuName` varchar (60),
`course` varchar (60),
`score` int
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('1','张三','语文','91');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('2','张三','数学','90');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('3','张三','英语','87');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('4','李四','语文','79');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('5','李四','数学','95');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('6','李四','英语','80');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('7','王五','语文','77');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('8','王五','数学','81');
insert into `t_grade` (`id`, `stuName`, `course`, `score`) values('9','王五','英语','89');
1、count()函数
1)统计记录的条数
SELECT COUNT(*) AS total FROM t_grade;
2)与group by 函数一起使用。
SELECT stuName,COUNT(*) FROM t_grade GROUP BY stuName;
张三 3
李四 3
王五 3
2、sum() 函数
1)求和
SELECT stuName,SUM(score) FROM t_grade WHERE stuName="张三";
2)与group by 函数一起使用
SELECT stuName,SUM(score) FROM t_grade GROUP BY stuName;
张三 268
李四 254
王五 247
3、avg() 函数
1)求平均值
SELECT stuName,AVG(score) FROM t_grade WHERE stuName="张三";
2)与group by 函数一起使用
SELECT stuName,AVG(score) FROM t_grade GROUP BY stuName;
4、max()/min() 函数
1)求最大值
SELECT stuName,course,MAX(score) FROM t_grade WHERE stuName="张三";
2)与group by 函数一起使用,此处不能加course 因为有stuName
SELECT stuName,MAX(score) FROM t_grade GROUP BY stuName;
连接查询:将两个或两个以上的表,按照某个条件连接起来,从中选择需要的数据。
笛卡尔乘积
SELECT * FROM t_book,t_booktype;
1、内连接查询
内连接查询是一种最常用的连接查询。内连接查询可以查询两个或两个以上的表。
SELECT * from t_book,t_booktype WHERE t_book.bookTypeId=t_booktype.id;
别名:
SELECT tb.bookName,tb.author,tby.bookTypeName from t_book tb,t_booktype tby WHERE tb.bookTypeId=tby.id;
2、外链接查询
外链接可以查出某一张表的所有信息
SELECT 属性名列表 from 表名1 left/right join 表名2 on 表名1.属性名1=表名2.属性名2
2.1左连接查询
可以查询出“表名1”的所有记录,而“表名2”中,只能查询出匹配的记录。不匹配的用null
SELECT * FROM t_book LEFT JOIN t_booktype ON t_book.bookTypeId=t_booktype.id;
别名:
SELECT tb.bookName,tb.author,tby.bookTypeName FROM t_book tb LEFT JOIN t_booktype tby ON tb.bookTypeId=tby.id;
2.2右连接查询
可以查询出“表名2”的所有记录,而“表名1”中,只能查询出匹配的记录。
SELECT * FROM t_book right JOIN t_booktype ON t_book.bookTypeId=t_booktype.id;
SELECT tb.bookName,tb.author,tby.bookTypeName FROM t_book tb right JOIN t_booktype tby ON tb.bookTypeId=tby.id;
3、多条件连接查询
SELECT tb.bookName,tb.author,tby.bookTypeName from t_book tb,t_booktype tby WHERE tb.bookTypeId=tby.id and tb.price>70;
子查询
create table `t_pricelevel` (
`id` int ,
`priceLevel` int ,
`price` float ,
`description` varchar (300)
);
insert into `t_pricelevel` (`id`, `priceLevel`, `price`, `description`) values('1','1','80.00','价格贵的书');
insert into `t_pricelevel` (`id`, `priceLevel`, `price`, `description`) values('2','2','60.00','价格适中的书');
insert into `t_pricelevel` (`id`, `priceLevel`, `price`, `description`) values('3','3','40.00','价格便宜的书');
1、带in关键字的查询
一个查询语句的条件可能落在另一个SELECT 语句的查询结果中。
select * from t_book where bookTypeId in (select id from t_booktype);
select * from t_book where bookTypeId not in (select id from t_booktype);
2、带比较运算符的查询(单一)
子查询可以使用比较运算符,查询出来的结果要是能够进行比较判断的,不能是集合
select * from t_book where price>=(select price from t_pricelevel where priceLevel=1);
3、带Exists关键字的查询
假如子查询查询到记录,则执行外层查询,否则,不执行外层查询。
select * from t_book where exists(select * from t_booktype);
select * from t_book where not exists(select * from t_booktype);
4、带ANY关键字的子查询(集合)
ANY关键字表示满足其中任一条件
select * from t_book where price >=ANY(select price from t_pricelevel);
5、带ALL关键字的查询
ALL关键字表示满足所有条件
select * from t_book where price >=ALL(select price from t_pricelevel);
合并查询
1、UNION
数据库系统会将所有的查询结果合并到一起,然后去除掉相同的记录。
select id from t_book union select id from t_booktype;
2、UNION ALL
数据库系统会将所有的查询结果合并到一起,不会除掉相同的记录。
select id from t_book union all select id from t_booktyp;
为表和字段取别名:
1、为表取别名
格式:表名 表的别名
select * from t_book tb where tb.id=1;
2、为字段取别名
格式:属性名 [AS] 别名
select tb.bookName bName from t_book tb where tb.id=1;
select tb.bookName as bName from t_book tb where tb.id=1;
插入、更新、删除数据
1、插入数据
给表的所有字段插入数据
格式:INSERT INTO 表名 VALUES (V1,V2,V3,...,Vn);
INSERT into t_book values (null,'数据库',23,风诺依曼,1);
INSERT into t_book (id,bookName,price,author,bookTypeId) values (null,'数据库',23,风诺依曼,1);
给表指定字段插入数据
格式:INSERT INTO 表名(属性1,属性2,...,属性n) VALUES (V1,V2,...,Vn);
INSERT into t_book (bookName,author)values ('数据库',风诺依曼);
同时插入多条记录
INSERT into t_book (id,bookName,price,author,bookTypeId)
values (null,'数据库',23,风诺依曼,1),
(null,'数据库2',23,风诺依曼,1)
(null,'数据库3',23,风诺依曼,1);
在SQL中如何向指定的某一行的某一列插入值:insert 不支持 where 用 update
更新数据
update t_book set bookName='JAVA编程思想',price=120 where id =1;
update t_book set bookName='数据原来' where bookName like '%我爱我家%';
删除数据
delete from t_book where id = 5;
索引
索引的引入
索引定义:索引由数据库表中一列或者多列组合而成,其作用是
提高对表中数据的查询速度;类似于图书的目录,方便快速定位,寻
找指定的内容。
索引的优缺点
优点:提高查询数据速度
缺点:创建和维护索引的时间增加
// 2016/1/6 复习至此处
索引分类
1.普通索引
可以创建在任何数据类型中
2.唯一性索引
使用UNIQUE参数可以设置,在创建唯一性索引时,限制该索引的值必须
是唯一的,主键默认是UNIQUE索引
3.全文索引
使用FULLTEXT参数设置,只能创建在CHAR,VARCHAR,TEXT类型
的字段上。主要作用就是提高查询较大字符串类型的速度,Mysql
默认引擎不支持全文索引
4.单列索引
在表中可以给单个字段创建索引
5.多列索引
表在多个字段上创建的索引
6.空间索引
使用SPATIAL参数可以设置空间索引,空间索引只能建立在空间
数据类型上,这样可以提高系统获取空间数据的效率。MYSQL默认引擎不支持
创建索引
1.创建表的时候创建索引
CREATE TABLE 表名(
属性名数据类型[完整性约束条件],
属性名数据类型[完整性约束条件],
....
属性名数据类型
[UNIQUE | FULLTEXT | SPATIAL ] INDEX| KEY
[别名] (属性名1 [(长度)] [ASC | DESC])
);
CREATE TABLE t_user1 (
id INT (11),
userName VARCHAR (20),
PASSWORD VARCHAR (20),
INDEX (userName)
);
唯一性索引
CREATE TABLE t_user2 (
id INT (11),
userName VARCHAR (20),
PASSWORD VARCHAR (20),
UNIQUE INDEX (userName)
);
取别名
CREATE TABLE t_user2 (
id INT,
userName VARCHAR (20),
PASSWORD VARCHAR (20),
INDEX index_userName (userName)
);
多列索引
CREATE TABLE t_user3 (
id INT,
userName VARCHAR (20),
PASSWORD VARCHAR (20),
INDEX index_userName_password (userName, PASSWORD)
);
2.在已存在的表上创建索引
在t_user3上的userName创建索引
create index index_userName on t_user3(userName); // 要有索引名
在t_user3上的userName创建唯一索引
create unique index index_userName on t_user3(userName);
在t_user3创建多列索引
create index index_userName_password on t_user3(userName,password);
3.用 ALTER TABLE 语句创建索引
alter table t_user3 add index index_userName(userName);
alter table t_user3 add unique index index_userName(userName);
alter table t_user3 add index index_userName_password(userName,password);
删除索引
drop index index_userName on t_user3;
视图
1,视图是一种虚拟的表,是从数据库中一个或者多个表中导出来的表。
2,数据库中只存放了视图的定义,而并没有存放视图中的数据,这些数据存放在原来的表中。
3,使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。
视图的作用
1,使操作简便化;
2,增加数据的安全性;
3,提高表的逻辑独立性;
1.创建视图
CREATE [ ALGORITHM ={ UNDEFIEND | MERGE | TEMPTABLE }]
VIEW 视图名[ ( 属性清单) ]
AS SELECT 语句
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ];
2.单表创建视图
CREATE VIEW v1 AS SELECT * from t_book;
CREATE VIEW v2 AS SELECT bookName,price from t_book;
SELECT * FROM v1;//只能查视图中的数据,其他的查不到,保证了安全性
CREATE VIEW v2(b,p) AS SELECT bookName,price from t_book; // 换掉视图栏位上的名字
3.多表创建视图
create view v4 as select tb.bookName,tby.bookTypeName from t_book tb ,t_booktype tby where tb.bookTypeId=tby.id;
4.查看视图
desc v2; // 查看视图的基本信息
show TABLE STATUS like 'v2'; // 查看视图基本信息,与上面的不同
show TABLE STATUS like 't_book';
show CREATE VIEW v2; // 查看视图详细信息
5.修改视图
create or replace view 语句修改视图
CREATE OR REPLACE [ ALGORITHM ={ UNDEFINED | MERGE | TEMPTABLE }]
VIEW 视图名[( 属性清单)]
AS SELECT 语句
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ];
CREATE
OR REPLACE VIEW v1 (bookName, price) AS SELECT
bookName,
price
FROM
t_book;
ALTER 语句修改视图
ALTER [ ALGORITHM ={ UNDEFINED | MERGE | TEMPTABLE }]
VIEW 视图名[( 属性清单)]
AS SELECT 语句
[ WITH [ CASCADED | LOCAL ] CHECK OPTION ];
ALTER VIEW v1 as SELECT * FROM t_book;
6.更新视图
更新视图是指通过视图来插入(INSERT)、更新(UPDATE)和删除(DELETE)表中的数据。因为视图是一个虚
拟的表,其中没有数据。通过视图更新时,都是转换基本表来更新。更新视图时,只能更新权限范围内的数据。
超出了范围,就不能更新。
插入数据
insert into v1 values(null,'java good',120,'fei',1);
更新数据
update v1 set bookName='java very good',price=200 where id=5;
删除数据
delete from v1 where id=5;
7.删除视图
删除视图是指删除数据库中已存在的视图。删除视图时,只能删除视图的定义,不会删除数据;
DROP VIEW [ IF EXISTS ] 视图名列表[ RESTRICT | CASCADE ]
drop view if exists v2;
触发器
触发器(TRIGGER)是由事件来触发某个操作。这些事件包括INSERT 语句、UPDATE 语句和DELETE 语句。
当数据库系统执行这些事件时,就会激活触发器执行相应的操作。
例子:在A表插入数据,触发B表插入数据
1.创建与使用触发器
创建只有一个执行语句的触发器
CREATE TRIGGER trig_book AFTER INSERT
ON t_book FOR EACH ROW
CREATE TRIGGER trig_book AFTER INSERT
ON t_book FOR EACH ROW
UPDATE t_booktype SET bookNum=bookNum+1 WHERE new.bookTypeId=t_booktype.id;
new 为过渡变量,代表插入后的新表
创建有多个执行语句的触发器
CREATE TRIGGER 触发器名BEFORE | AFTER 触发事件
ON 表名FOR EACH ROW
BEGIN
执行语句列表
END
CREATE TRIGGER trig_book2 AFTER DELETE
on t_book FOR EACH ROW
BEGIN
UPDATE t_booktype SET bookNum=bookNum-1 WHERE new.bookTypeId=t_booktype.id;
INSERT INTO t_log VALUES (null,'在t_book表中删除了一条数据');
DELETE FROM t_test WHERE old.bookTypeId=t_test.id;
END
// 下述语句在数据库中执行错误,且没有修改正确
delimiter |
CREATE TRIGGER trig_book2 AFTER DELETE
on t_book FOR EACH ROW
BEGIN
UPDATE t_booktype SET bookNum=bookNum-1 WHERE old.bookTypeId=t_booktype.id;
INSERT INTO t_log VALUES (null,NOW(),'在t_book表中删除了一条数据');
DELETE FROM t_test WHERE old.bookTypeId=t_test.id;
END
|
delimiter;
3.查看触发器
SHOW TRIGGERS 语句查看触发器信息 ==>所有触发器
4.删除触发器
DROP TRIGGER 触发器名;
MySQL数据库基本指令(全)的更多相关文章
- MySQL数据库基本指令
对MySQL的指令不太熟悉,在此特别整理了一下一些常用的指令: 约定:大写字母写SQL关键字和函数名,小写字母写数据库.数据表和数据列的名字.(下述代码更新不同步,部分代码未依据此约定) 1 数据库的 ...
- mysql数据库操作指令汇总
1.mysql -u root -p 登录数据库 2.表结构相同两表数据对拷 insert into A select * from B(插入全部字段数据) insert into A(字段1.字 ...
- Mysql数据库基础知识(全)
前言:本博文为个人笔记,记录了Mysql的一些基本操作,一般掌握本博文就可以了解数据库.表.数据项的增删改查,希望对大家的学习有所帮助. 首先下载PHPSTUDY,将Mysql配置为系统变量. 具体操 ...
- mysql数据库操作指令
数据库相关 查询所有数据库 show databases; 创建数据库 create database 数据库名: 创建数据库指定字符集 create database 数据库名 character ...
- 从零开始的全栈工程师——MySQL数据库( Dos命令 ) ( phpstudy )
MySQL是一个关系型数据库,存在表的概念.结构,数据库可以存放多张表,每个表里可以存放多个字段,每个字段可以存放多个记录. phpstudy使用终端打开数据库的命令行 密码: root 数据库 查看 ...
- mysql数据库指令导入导出
mysql数据库导出使用 /mysql/bin/mysqldump指令 数据库导出 导出指令: [mysql安装目录]/bin/mysqldump -u[username] -p[password] ...
- Xtrabackup全量备份与恢复mysql数据库
一.Xtrabackup简单概述: Percona Xtrabackup是开源免费的MySQL数据库热备份软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同 ...
- mysql数据库,什么是数据库的全备份?
需求描述: 今天要做mysql数据库的全备份,那么就要弄清楚一个概念,到底什么是数据库的全备份呢. 概念解释: 数据库的全备份,就是在一个给定的时间点,对于mysql服务器管理的所有的数据进行备份. ...
- 超全面的JavaWeb笔记day15<mysql数据库>
1.数据库的概述 2.SQL 3.DDL 4.DML 5.DCL 6.DQL MySQL 数据库 1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优 ...
随机推荐
- 2015腾讯web前端笔试题
1 请实现,鼠标点击页面中的任意标签,alert该标签的名称.(注意兼容性) 2 请指出一下代码的性能问题,并经行优化. var info="腾讯拍拍网(www.paipai.com)是 ...
- c++ 左值 和 右值
什么是lvalue, 什么是rvalue? lvalue: 具有存储性质的对象,即lvalue对象,是指要实际占用内存空间.有内存地址的那些实体对象,例如:变量(variables).函数.函数指针等 ...
- Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解
废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面. 本文内容: Java代码中动态生成View Java代码中动态设置View的位置,以及其他的属性 LayoutParams详解 一 ...
- java中的三种取整函数
舍掉小数取整:Math.floor(3.5)=3 四舍五入取整:Math.rint(3.5)=4 进位取整:Math.ceil(3.1)=4
- 利用pushState开发无刷页面切换
转载:http://www.cnblogs.com/flash3d/archive/2013/10/23/3384823.html 实现目标 页面的跳转(前进后退,点击等)不重新请求页面 页面URL与 ...
- 廖雪峰js教程笔记3
JavaScript的函数在查找变量时从自身函数定义开始,从"内"向"外"查找.如果内部函数定义了与外部函数重名的变量,则内部函数的变量将"屏蔽&qu ...
- poj2796 维护区间栈//单调栈
http://poj.org/problem?id=2796 题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以 ...
- 《DSP using MATLAB》示例Example5.4
- 《DSP using MATLAB》示例Example4.3 双边序列
- PHP 二分查找(详细)
<?php // PHP 二分查找 function search($arr, $sea){ $low = 0; // 确定数组的开始的下标 $len ...