【前端面试】数据库

例题1

下面关于 InnoDB 存储引擎和 MyISAM 存储引擎正确的是()
A InnoDB 支持行级锁和表级锁,而 MyISAM 支持表级锁
B InnoDB 支持全文索引,而 MyISAM 不支持全文索引
C InnoDB 不支持事务,而 MyISAM 支持事务
D InnoDB 不支持外键,而 MyISAM 支持外键

解析

这道题目考察的是 MySQLInnoDBMyISAM 两种存储引擎的区别

  • A InnoDB 支持 行级锁表级锁,其中行级锁是 InnoDB 的一个重要特性,有助于提高并发性能
    MyISAM 只支持表级锁,每次对表进行增删改操作时,都会锁住整个表,限制了并发处理能力
  • B MyISAMInnoDB 更早支持全文索引(Full-Text Index)。MyISAM 早期版本就已经支持全文索引,适用于文本搜索功能。
    InnoDBMySQL 5.6 开始支持全文索引,但这是相对较新的功能。
  • C InnoDB 支持事务,这也是它的一个关键特性,能够提供 ACID(原子性、一致性、隔离性、持久性)保障,使其适合需要事务处理的应用场景。
    MyISAM 不支持事务,它不保证数据的回滚和一致性,因此不适合事务性要求较高的场景。
  • D InnoDB 支持外键,可以强制参照完整性约束,以维护表之间的数据一致性。
    MyISAM 不支持外键,其表结构设计相对简单,没有外键约束。

例题2

有一张电话表(telephones),id是主键,send_id表示打电话人的id,receive_id表示接电话人的id,type表示电话是否打成功:
在这里插入图片描述
还有一张用户表(users),id也是主键,is_blacklist列中的1 代表该用户是骚扰用户,即他的电话不会打成功,会被系统拦截。
在这里插入图片描述
现要查询每天的正常用户给正常用户打电话,无法接通(可能是信号不好、电话欠费等原因导致)的概率,结果保留到小数点后两位,并按日期降序排列。比如上面示例就会得到如下结果
在这里插入图片描述
(注意: sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5,sqlite四舍五入的函数为round)
下列sqlite查询语句正确的是()
A
B
C
D

解析

A

SELECT
    t.date,
    ROUND(
        SUM(
            CASE WHEN t.type = 'no_completed' THEN 1 ELSE 0 END
        ) * 1.0 / COUNT(t.type),
    2) AS p
FROM
    telephones t
JOIN users u1 ON t.send_id = u1.id
AND u1.is_blacklist = 0
JOIN users u2 ON t.receive_id = u2.id
AND u2.is_blacklist = 0
GROUP BY
    t.date
ORDER BY
    t.date DESC;
  • SUM(CASE WHEN t.type = 'no_completed' THEN 1 ELSE 0 END)
    这段代码通过 CASE 语句计算通话失败的数量,即 type'no_completed' 时加 1,否则加 0
  • * 1.0 / COUNT(t.type)
    用总的失败通话数除以当天所有通话的总数,* 1.0 确保执行浮点数除法,而不是整数除法,从而计算出失败通话的比例。
  • JOIN users u1 and JOIN users u2
    telephones 表中的 send_idreceive_id 分别与 users 表的 id 连接,确保通话双方都不是黑名单用户(is_blacklist = 0),这样只有符合条件的通话才会被计算
  • ROUND(..., 2)
    使用 ROUND 函数将结果保留两位小数
  • GROUP BY t.dateORDER BY t.date DESC
    按照 date 分组和降序排列,保证每一天的通话比例分别计算并按日期从最近到最远排序

B

SELECT
    t.date,
    ROUND(
        SUM(
            CASE t.type WHEN 'completed' THEN 0 ELSE 1 END
        ) * 1.0 / COUNT(t.type),
    2) AS p
FROM
    telephones AS t,
    users as u
WHERE
    t.send_id = u.id
    AND t.receive_id = u.id
    AND u.is_blacklist = 0
GROUP BY
    t.date
ORDER BY
    t.date DESC;
  • SUM(CASE t.type WHEN 'completed' THEN 0 ELSE 1 END)
    这里试图通过 CASE t.type 来判断通话的类型,但 CASE 语法错误。应该用 CASE WHEN 而不是 CASE t.type WHEN
    此外,'completed' 代表通话成功,0 对应成功通话,1 对应其他情况(失败)。逻辑上与题意相符。
  • 错误的表连接
    FROM telephones AS t, users as u:这里在 WHERE 子句中试图将 send_idreceive_id 都连接到同一个用户表 users,这不符合逻辑。因为 send_idreceive_id 分别代表打电话人和接电话人,它们应该连接到两个用户实体,而不是同一个用户。
    逻辑上应该像 A 选项那样,分开 send_idreceive_id 对应到不同的 users 表中的用户。

C

SELECT
    t.date,
    ROUND(
        SUM(
            CASE WHEN t.type = 'no_completed' THEN 1 ELSE 0 END
        ) / COUNT(t.type),
    2) AS p
FROM
    telephones t
JOIN users u1 ON t.send_id = u1.id
AND u1.is_blacklist = 0
JOIN users u2 ON t.receive_id = u2.id
AND u2.is_blacklist = 0
GROUP BY
    t.date
ORDER BY
    t.date DESC;
  • 缺少 * 1.0
    这里的 SUM(...) / COUNT(t.type) 没有乘以 1.0,导致在某些数据库中可能会执行整数除法,而不是浮点数除法,可能会出现计算精度丢失的问题。

D

SELECT
    t.date,
    ROUND(
        SUM(
            CASE WHEN t.type = 'no_completed' THEN 1 ELSE 0 END
        ) * 1.0 / COUNT(t.type),
    2) AS p
FROM
    telephones
JOIN users u1 ON t.send_id = u1.id
AND u1.is_blacklist = 0
JOIN users u2 ON t.receive_id = u2.id
AND u2.is_blacklist = 0
GROUP BY
    t.date
ORDER BY
    t.date DESC;
  • 没有指定 telephones 的别名
    查询中的 FROM telephones 没有给表 telephones 指定别名 t,但是在后面的查询中使用了 t.send_idt.receive_id,这会导致 SQL 报错,找不到表 t

例题3

在MySQL中可以用来执行预处理语句的是()
A execute
B prepare
C deallocate
D using

解析

PREPARE语句准备好一条SQL语句,并分配给这条SQL语句一个名字供之后调用。准备好的SQL语句通过EXECUTE命令执行,通过DEALLOCATE PREPARE或者DEALLOCATE命令释放掉。

补充

预处理

语句的名字不区分大小写。准备好的SQL语句名字可以是字符串,也可以是用户指定的包含SQL文本的变量。PREPARE中的SQL文本必须代表一条单独的SQL语句而不能是多条SQL语句。在SQL语句中,? 字符用来作为后面执行查询使用的一个参数。? 不能加上引号,即使打算将它们绑定到字符变量中也不可以 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值