Jerry's Blog

Recording what I learned everyday

View on GitHub


6 August 2019

Database(4) -- CRUD

by Jerry Zhang

LeetCode Day 32: P203. Remove Linked List Elements (Easy)

题目:

给一个数和一个链表,删除链表中所有等于这个数的节点。

Input:  1->2->6->3->4->5->6, val = 6
Output: 1->2->3->4->5

思路:

链表的基本操作,似乎没什么需要注意的。。。

答案:

第一次我的代码有bug,按正确的稍稍改了一下。

public class E_203_RemoveLinkedListElements {
    public ListNode removeElements(ListNode head, int val) {
        ListNode sentinel = new ListNode(0);
        sentinel.next = head;

        ListNode position = sentinel;
        while(position.next != null) {
            if (position.next.val == val) {
                position.next = position.next.next;
            } else {
                position = position.next;
            }
        }
        return sentinel.next;
    }
}

Database: CRUD

InnoDB

MyISAM不支持事务。在写入数据时锁表。如果连续写入多条数据,无法一起回滚。

InnoDB是默认引擎。支持事务,锁表->行锁,适合读多写多。2000万以上读写速度会明显下降。

TokuDB只支持Linux,适合用于不常用的过期数据,归档表。写入 速度快。写多读少。

Ignore 关键字

INSERT IGNORE INTO t_dept(deptno, dname, loc)
VALUES  (40, "企划部", "北京"),
        (50, "培训部", "上海"),
        (60, "后勤部", "北京"),
        (70, "技术部", "北京"),
        (80, "市场部", "北京");

加IGNORE关键字,可以忽略错误,事务不回滚,其他正确的项目正常插入。

存在就更新,不存在就插入

ON DUPLICATE KEY UPDATE

INSERT INTO t_emp_ip(id,empno,ip) VALUES
    (5, 8004, "192.168.99.44"),
    (6, 8005, "192.168.99.45"),
    (7, 8006, "192.168.99.46"),
    (8, 8001, "192.168.99.47")
ON DUPLICATE KEY UPDATE ip=VALUES(ip);

自动判断是否违反了主键约束和唯一性约束,如果存在就更新。

子查询

MySQL默认关闭了缓存,所以每个子查询都是相关子查询,要执行多次。

SELECT empno, ename FROM t_emp
    WHERE sal > (
        SELECT sal FROM t_emp WHERE empno = 7499
    )
    AND empno != 7499;

MyBatis, Hibernate 等框架开启了缓存,所以可以使用子查询。

可以使用FROM子查询,替代WHERE子查询。

SELECT e.empno, e.ename FROM t_emp e 
    JOIN (SELECT sal FROM t_emp WHERE empno = 7499) t 
    ON e.sal > t.sal AND e.empno != 7499

from 子句是确定数据来源,是最先执行的,只会执行一次。

内连接和外连接

在内连接(只有JOIN关键字)里,查询条件写在ON子句或者WHERE子句效果相同。

在外连接(比如LEFT JOIN)里,如果把查询条件写在ON子句,就会包含所有的左表数据。而如果把条件写在WHERE子句里,那左表只有满足条件的才 可以被检索出来。

UPDATE中的表连接

错误写法:

UPDATE t_emp SET sal=10000 WHERE deptno = 
(SELECT deptno FROM t_dept WHERE dname = 'SALES');

正确写法:

UPDATE t_emp e JOIN t_dept d ON e.deptno = d.deptno
AND d.dname = 'SALES'
SET e.sal = 10000, d.dname = "销售部";

DELETE语句中的表连接

DELETE e, d FROM t_emp e JOIN t_dept d
    ON e.deptno = d.deptno AND d.dname='销售部';

事务机制

redo日志和undo日志: 先拷贝到undo日志,修改记录,生成redo日志,最后用redo日志同步记录。

ACID:

tags: Database