请问 select(1) 和 select(*) 有什么区别
selelct 常量 from ...
对应所有行,返回的永远只有一个值,即常量
。所以正常只会用来判断是否有还是没有,比如 exists 子句。select * from …
是返回所有行的所有列。 性能上的差异,关键看 from 和 where 子句,比如说 where 条件中可以使用索引,那显然select 1 from …
的性能比select * from …
好。
说一下 count(1) 和 count(*) 的区别
count(*)
包括了所有的列,相当于行数,在统计结果的时候,不会忽略为 NULL
的值。
count(1)
包括了忽略所有列,用 1 代表代码行,在统计结果的时候,不会忽略为 NULL 的值。
count(列名)
只包括列名那一列,在统计结果的时候,会忽略列值为空的计数,即某个字段值为 NULL 时,不统计。这里的空不是指空字符串或者 0,而是表示 null
。
执行效率上:
- 列名为主键,
count(列名)
会比count(1)
快; - 列名不为主键,
count(1)
会比count(列名)
快; - 如果表多个列并且没有主键,则
count(1)
的执行效率优于count(*)
; - 如果有主键,则
select count(主键)
的执行效率是最优的; - 如果表只有一个字段,则
select count(*)
最优。
说一下 B-Tree 索引
B-Tree
能加快数据的访问速度,因为存储引擎不再需要进行全表扫描来获取数据,数据分布在各个节点之中。
在 MySQL 中不同存储引擎使用 B-Tree
索引的方式不尽相同,同样会影响数据库的性能,比如 MyISAM 引擎使用一种“前缀压缩”的技术,这样可以索引更小,并且 MyISAM 索引是通过索引到具体物理地址找到数据行的。而 InnoDB 引擎则在索引中保留了未压缩的值,InnoDB 是通过主键值来索引到数据行的。这两种方式各有优缺点。
B-Tree
索引之所以能够加快数据访问速度,主要是因为存储引擎在访问要查找的数据时不需要进行全表扫描。它是从 B-Tree 的根节点开始的,根节点的槽保存着指向子节点的指针,存储引擎会跟随这些指针,然后通过查看节点页中的值从而找到正确指针,这个指针定义了其子节点中值得上限和下限。最终结果为存储引擎没有查找到期望的值,或者成功到达叶子页。
查询类型可以使用 B-Tree 索引
B-Tree
索引在根据完整键值、键范围或者键前缀查找时性能比较好,这些只有在使用索引的最左前缀时有效(最左索引可能是 MySQL 的特列)。下面这几种类型查询使用前面说的索引是很有用的:
1、匹配全值,一个全键值匹配索引中所有列的指定值,也就是根据索引列的值来匹配。
2、匹配最左前缀,只根据索引最左列值查找。
3、匹配某一列的前缀,即根据索引列的值的前缀查找,这种情况只能使用到索引第一列的情景。
4、匹配值区间,即根据索引某一列值范围查找,也只能是索引列第一列。
5、匹配一部分精确值,一部分范围值,比如我索引有两列 A、B,可以根据 A 列的精确值,B 列的范围值进行查询。
6、仅索引查询。B-Tree
索引支持仅索引查询,这种情况只会访问本身,而不会访问行存储。
因为树的节点是有序排列的,因此可以用来根据(查找值)查找和 order by 查询(有序方式查找值)。通常来说,如果一个 B-Tree
可以通过某种特定方式查找某一行,它也可以按相同条件对行进行排序。所以索引对满足上面列出查找类型的 order by 子句很有帮助。
B-Tree 的一些限制
1、不满足最左索引的查找是没有用的,比如索引是 A 、B 列,但是查询条件是 where B = "b"
。
2、不能跳过索引中的列,比如索引还是 A 、B 列,但是查询条件是 A = "a" and C ="c"
这种明显是不行的。
3、存储引擎无法对第一个范围查找右侧的列访问进行优化。比如索引列是 A、B、C 三列,而查询是 select * from table where A = "a" and B like "b" and C = "c"
,这种情况下索引访问只会访问前两列,因为 like
也是一个范围查询。
B-Tree
索引作为最常用的索引类型,它通过以有序方式对数据进行排序运行,这样 MySQL 就可以利用诸如 order by
、group by
这样查询语句。因为数据是已经排好序的,B-Tree
索引可以将数据关联存储在一起。最后就是,索引本身实际上保存了数据值副本,因此某些情况下只通过索引就能满足查询结果。
JDBC API 的 PreparedStatement 相比 Statement 的好处
大多数时候都使用 PreparedStatement 代替 Statement。
1、PreparedStatement 是预编译的,比 Statement 速度快;
2、PreparedStatement 代码的可读性和可维护性更好。虽然用 PreparedStatement 来代替 Statement 会使代码多出几行,但这样的代码无论从可读性还是可维护性上来说,都比直接用 Statement 的代码高很多档次:
代码语言:javascript复制// Statement
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('" var1 "','" var2 "'," var3 ",'" var4 "')");
// preparedStatement
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(,var1);
perstmt.setString(,var2);
perstmt.setString(,var3);
perstmt.setString(,var4);
perstmt.executeUpdate();
3、安全性。PreparedStatement 可以防止 SQL 注入攻击,而 Statement 却不能。比如说:
代码语言:javascript复制String sql = "select * from tb_name where name= '" varname "' and passwd='" varpasswd "'";
// 如果把 [' or '1' = '1] 作为 varpasswd 传入进来,用户名 xx,看看会成为什么?
select * from tb_name where name = 'xx' and passwd = '' or '1' = '1';
// 因为 '1'='1' 肯定成立,所以可以任何通过验证,更有甚者:
// 把 [';drop table tb_name;] 作为 varpasswd 传入进来,则:
select * from tb_name where name = '随意' and passwd = '';drop table tb_name;
// 有些数据库是不会成功的,但也有很多数据库就可以使这些语句得到执行。
// 而如果使用预编译语句传入的任何内容就不会和原来的语句发生任何匹配的关系,
// 只要全使用预编译语句就用不着对传入的数据做任何过虑。
// 而如果使用普通的 statement,有可能要对 drop 等做费尽心机的判断和过虑。
JDBC API 中的 execute,executeQuery,executeUpdate 的区别是什么?
Statement 的 execute(String query)
方法用来执行任意的 SQL 查询,如果查询的结果是一个 ResultSet
,这个方法就返回 true
。如果结果不是 ResultSet
,比如 insert
或者 update
查询,它就会返回 false
。可以通过它的 getResultSet
方法来获取 ResultSet
,或者通过 getUpdateCount()
方法来获取更新的记录条数。
Statement 的 executeQuery(String query)
接口用来执行 select
查询,并且返回 ResultSet
。即使查询不到记录返回的 ResultSet
也不会为 null
。通常使用 executeQuery
来执行查询语句,这样的话如果传进来的是 insert
或者 update
语句的话,它会抛出错误信息为 executeQuery method can not be used for update
的 java.util.SQLException
。
Statement 的 executeUpdate(String query)
方法用来执行 insert
或者 update/delete
DML 语句,或者什么也不返回 DDL 语句。返回值是 int
类型,如果是 DML 语句的话,它就是更新的条数,如果是 DDL 的话,就返回 0。
只有不确定是什么语句的时候才应该使用 execute()
方法,否则应该使用 executeQuery
或者 executeUpdate
方法。
JavaScript 中的 `==` 和 `===` 的不同
==
只比较值,===
比较值和数据类型。
AJAX 的优缺点都有什么?
优点:
1)页面无刷新,用户的体验非常好。
2)使用异步方式与服务器通信,具有更加迅速的响应能力。
3)可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,AJAX 的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4)基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
缺点:
1)不支持浏览器 back
按钮。
2)安全问题,AJAX 暴露了与服务器交互的细节。
3)对搜索引擎的支持比较弱。
4)破坏了程序的异常机制。
5)不容易调试。
请简要说明 `String.valueOf` 和 `(String)` 以及 `toString` 的区别
(String)
强制类型转换,要注意的是类型必须能转成 String 类型。toString
字符串类型转换,要注意,必须保证 object 不是 null 值,否则将抛出NullPointerException
异常。String.valueof()
当转入的变量为null
时,不会报错。
反射机制的优缺点?
静态编译 - 在编译时确定类型、绑定对象即通过。
动态编译 - 在运行时确定类型、绑定对象。动态编译最大限度发挥了 Java 的灵活性,体现了多态的应用,有以降低类之间的藕合性。
优点: 可以实现动态创建对象和编译,体现出很大的灵活性,特别是在 J2EE 的开发中,它的灵活性就表现的十分明显。
缺点: 对性能有影响。使用反射基本上是一种解释操作,可以告诉 JVM,希望做什么并且它满足对应的要求。这类操作总是慢于只直接执行相同的操作。
什么是 JDBC 连接,在 Java 中如何创建一个 JDBC 连接?
JDBC 的全称是 Java DataBase Connection,也就是 Java 数据库连接,可以用它来操作关系型数据库。JDBC 接口及相关类在 java.sql
包和 javax.sql
包里。可以用它来连接数据库,执行 SQL 查询,存储过程,并处理返回的结果。
创建 JDBC 连接:
1、加载 JDBC 驱动程序。
2、提供 JDBC 连接的 URL。
3、创建数据库的连接。
4、创建一个 Statement。
5、执行 SQL 语句。
6、处理结果。
7、关闭 JDBC 对象。