Sunteți pe pagina 1din 12

Agenda

Revision
Constraints: Foreign Key Constraint
SubQueries
Transactions
Locking
Views
Temporary tables
MySQL variables
MySQL Programming

Revision
Indexes

Used for faster searching (WHERE clause).


Index contains column values and addresses of corresponding records on disk.
Indexes are stored on server disk in specialized formats. In MySQL they are
stored as BTREE or HASH.
Types:

Normal index

On single column.
Values can duplicate.
CREATE INDEX idx_name ON tbl_name(col_name [ASC|DESC]);

Composite index

On combination of multiple columns.


Values can duplicate.
CREATE INDEX idx_name ON tbl_name(col1_name, col2_name,
...);

Unique index

On single column or combination of multiple columns.


Values cannot be duplicated.
CREATE UNIQUE INDEX idx_name ON tbl_name(col_name
[ASC|DESC]);
CREATE UNIQUE INDEX idx_name ON tbl_name(col1_name,
col2_name, ...);

To show indexes:

SHOW INDEXES FROM tbl_name;

To drop indexes:

DROP INDEX idx_name ON tbl_name;


Limitations:

DML is slower.
Index creation slower.
Index need space of disk.

Indexes should not be created on TEXT or BLOB for performance reason


(because they are stored outside the record).
In MySQL, while creating index on TEXT or BLOB, the length should be
specified.

CREATE INDEX idx_name ON tbl_name(text_col(10));

Primary Key

Constraint on column.
It is equivalent to combination of NOT NULL and UNIQUE constraint.
However, only one Primary Key for the table.

CREATE TABLE tbl_name(


col1 type PRIMARY KEY,
col2 type,
col3 type
);

CREATE TABLE tbl_name(


col1 type,
col2 type,
col3 type,
PRIMARY KEY (col1)
);

CREATE TABLE tbl_name(


col1 type,
col2 type,
col3 type,
CONSTRAINT constraint_name PRIMARY KEY (col1)
);

ALTER TABLE tbl_name ADD PRIMARY KEY (col1);

Decide Primary Key

It is done while normalization.


Natural Primary Key

Unique column in the table.

Composite Primary Key

Unique combination of columns in the table.

Surrogate Primary Key

Adding extra column as unique id of the row.


Usually these are int or guid.

Primary Key (AUTO_INCREMENT)

CREATE TABLE items(id INT AUTO_INCREMENT PRIMARY KEY, name


VARCHAR(30), `desc` VARCHAR(30));

INSERT INTO items(name, `desc`) VALUES('Paper', 'A4');


INSERT INTO items(name, `desc`) VALUES('Pencil', 'HB');
INSERT INTO items(name, `desc`) VALUES('Pen', 'Red Ballpen');

SELECT * FROM items;

ALTER TABLE items AUTO_INCREMENT = 100;


INSERT INTO items(name, `desc`) VALUES('Pen', 'Blue Ballpen');

SELECT * FROM items;

DELETE FROM items;

INSERT INTO items(name, `desc`) VALUES('Pen', 'Black Ballpen');

SELECT * FROM items;

Constraint
Types:

NOT NULL
UNIQUE
CHECK
PRIMARY KEY
FOREIGN KEY

FOREIGN Key
When tables are related (parent-child), PRIMARY key of parent table is associated with a
column in child table.
To enforce verifying this column should contain a value corresponding to Primary key of
parent table, Foreign key constraint is applied.
CREATE TABLE dept (deptno INT PRIMARY KEY, dname VARCHAR(20));
INSERT INTO dept VALUES (10, 'DEV');
INSERT INTO dept VALUES (20, 'QA');
INSERT INTO dept VALUES (30, 'OPS');
INSERT INTO dept VALUES (40, 'ACC');

CREATE TABLE emp (


empno INT,
ename VARCHAR(20),
deptno INT,
FOREIGN KEY (deptno) REFERENCES dept(deptno)
);
INSERT INTO emp VALUES (1, 'Amit', 10);
INSERT INTO emp VALUES (2, 'Rahul', 10);
INSERT INTO emp VALUES (3, 'Nilesh', 20);
INSERT INTO emp VALUES (4, 'Nitin', 50); -- error
INSERT INTO emp VALUES (5, 'Sarang', 50); -- error

CREATE TABLE student(


std INT,
roll INT,
name VARCHAR(20),
PRIMARY KEY(std, roll);
);

CREATE TABLE result(


std INT,
roll INT,
subject VARCHAR(20),
marks INT,
FOREIGN KEY (std,roll) REFERENCES student(std,roll)
);

Disable Foreign key

Foreign key checks ensures data integrity, but make DML slower.
For data porting/backup, this slowdown the operations.
Here Foreign keys can be disabled temporarily.
In MySQL this can be using system variable foreign_key_checks.
SHOW VARIABLES;

SHOW VARIABLES LIKE 'foreign%';

SELECT @@foreign_key_checks;

SET @@foreign_key_checks=0;

INSERT INTO emp VALUES (4, 'Nitin', 50); -- okay


INSERT INTO emp VALUES (5, 'Sarang', 50); -- okay

SET @@foreign_key_checks=1;

INSERT INTO emp VALUES (6, 'Vishal', 50); -- error

Parent rows cannot be deleted (if there are corresponding child rows).

Parent table connot be dropped (if child some table is present).

DELETE FROM dept WHERE deptno=40; -- okay

DELETE FROM dept WHERE deptno=20; -- error

DELETE FROM emp WHERE ename='Nilesh';

DELETE FROM dept WHERE deptno=20; -- okay

DROP TABLE dept; -- error

DROP TABLE emp;

DROP TABLE dept; -- okay

ON DELETE CASCADE and ON UPDATE CASCADE both features can be used together.

These features are MySQL specific.


CREATE TABLE dept (deptno INT PRIMARY KEY, dname VARCHAR(20));
INSERT INTO dept VALUES (10, 'DEV');
INSERT INTO dept VALUES (20, 'QA');
INSERT INTO dept VALUES (30, 'OPS');
INSERT INTO dept VALUES (40, 'ACC');

CREATE TABLE emp (


empno INT,
ename VARCHAR(20),
deptno INT,
FOREIGN KEY (deptno) REFERENCES dept(deptno) ON DELETE CASCADE
);
INSERT INTO emp VALUES (1, 'Amit', 10);
INSERT INTO emp VALUES (2, 'Rahul', 10);
INSERT INTO emp VALUES (3, 'Nilesh', 20);

SELECT * FROM dept;

SELECT * FROM emp;

DELETE FROM dept WHERE deptno=10;

UPDATE dept SET deptno=60 WHERE dname='QA'; -- error

CREATE TABLE dept (deptno INT PRIMARY KEY, dname VARCHAR(20));


INSERT INTO dept VALUES (10, 'DEV');
INSERT INTO dept VALUES (20, 'QA');
INSERT INTO dept VALUES (30, 'OPS');
INSERT INTO dept VALUES (40, 'ACC');

CREATE TABLE emp (


empno INT,
ename VARCHAR(20),
deptno INT,
FOREIGN KEY (deptno) REFERENCES dept(deptno) ON UPDATE CASCADE
);
INSERT INTO emp VALUES (1, 'Amit', 10);
INSERT INTO emp VALUES (2, 'Rahul', 10);
INSERT INTO emp VALUES (3, 'Nilesh', 20);

SELECT * FROM dept;

SELECT * FROM emp;

UPDATE dept SET deptno=60 WHERE dname='QA'; -- okay

SubQueries
Query within query. (SELECT query within SELECT query).
Single row sub-query
When sub-query returns single row.

-- Find all emps whose sal is more that avg sal of emps.
SELECT AVG(sal) FROM emp;

SELECT * FROM emp WHERE sal > 2073.214286;

SET @avgsal=(SELECT AVG(sal) FROM emp);

SELECT @avgsal;

SELECT * FROM emp WHERE sal > @avgsal;

SELECT * FROM emp WHERE sal > (SELECT AVG(sal) FROM emp);

-- Find emp with 3rd highest sal.


SELECT * FROM emp ORDER BY sal DESC;

SELECT * FROM emp ORDER BY sal DESC LIMIT 2,1;

SELECT DISTINCT sal FROM emp ORDER BY sal DESC LIMIT 2,1;

SET @sal3 = (SELECT DISTINCT sal FROM emp ORDER BY sal DESC LIMIT 2,1);

SELECT @sal3;

SELECT * FROM emp WHERE sal = @sal3;

SELECT * FROM emp WHERE sal = (SELECT DISTINCT sal FROM emp ORDER BY sal DESC
LIMIT 2,1);

Multi-row SubQuery
When sub-query returns more than one row.
To compare values returned from Multi row subquery we can use ALL or ANY keyword.
ALL operator

value is compared with all the values returned from subquery. When all are
matched the result is processed further.
it is logical AND.

ANY operator

value is compared with the values returned from subquery. When any one is
matched the result is processed further.
it is logical OR.
-- Display emps whose sal is more than sal of all salesman.
SELECT MAX(sal) FROM emp WHERE job='SALESMAN';

SELECT * FROM emp WHERE sal > (SELECT MAX(sal) FROM emp WHERE job='SALESMAN');

SELECT sal FROM emp WHERE job='SALESMAN';

SELECT * FROM emp WHERE sal > ALL(SELECT sal FROM emp WHERE job='SALESMAN');

-- Display emps whose sal is more than sal of any salesman.


SELECT MIN(sal) FROM emp WHERE job='SALESMAN';

SELECT * FROM emp WHERE job != 'SALESMAN' AND sal > (SELECT MIN(sal) FROM emp
WHERE job='SALESMAN');

SELECT sal FROM emp WHERE job='SALESMAN';

SELECT * FROM emp WHERE job != 'SALESMAN' AND sal > ANY(SELECT sal FROM emp
WHERE job='SALESMAN');

-- Display depts in which emps are there.


SELECT deptno FROM emp;

SELECT * FROM dept WHERE deptno = ANY(SELECT deptno FROM emp);

SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp);

Correlated SubQueries
By default (if not optimized by database), for each row of outer query, inner query is
executed. This makes subqueries slower.
To make subqueries faster, we can write subqueries so that inner query produces lesser
number of rows.
This is done by referencing outer row from inner query. Such query is called as
"Correlated subquery".
-- Display depts in which emps are there.
SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp);

SELECT * FROM dept d


WHERE deptno IN (SELECT deptno FROM emp e WHERE e.deptno = d.deptno);

EXPLAIN FORMAT=JSON
SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp);

EXPLAIN FORMAT=JSON
SELECT * FROM dept d
WHERE deptno IN (SELECT deptno FROM emp e WHERE e.deptno = d.deptno);

SELECT * FROM dept d


WHERE (SELECT COUNT(deptno) FROM emp e WHERE e.deptno = d.deptno) > 0;

-- Display depts in which num of emps > 0.

EXPLAIN FORMAT=JSON
SELECT * FROM dept d
WHERE (SELECT COUNT(deptno) FROM emp e WHERE e.deptno = d.deptno) > 0;

-- Display depts in which emps exists.

SELECT * FROM dept d


WHERE EXISTS (SELECT deptno FROM emp e WHERE e.deptno = d.deptno);

-- Display depts in which emps doesn't exists.

SELECT * FROM dept d


WHERE NOT EXISTS (SELECT deptno FROM emp e WHERE e.deptno = d.deptno);

EXISTS operator check whether subquery returns one or more rows. NOT EXISTS
operator check whether subquery returns 0 rows.

SubQuery in UPDATE & DELETE


In MySQL, we cannot update on delete from table, if same table is used for inner query.
In MySQL, we can update on delete from table, if same table is not used for inner query.

DELETE FROM emp WHERE sal < (SELECT AVG(sal) FROM emp); -- err in MySQL

DELETE FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); -- okay

Query performance
Usually subqueries are slower than joins (when no optimization is done).
But using some of the optimization switches, few subqueries tend to execute faster
than joins.
Query optimization switches in MySQL are accessible using @@optimizer_switch.
One of the switch is materialization. When it is on and if applicable, result of subquery
is cached into a temporary table. Due to this there is no need of executing subquery
again and again (for each row of outer query).
Another switch is block_nested_loop, which converts subquery into a nested loop (like
join). This will also improve the performance.

EXPLAIN FORMAT=JSON
SELECT * FROM dept WHERE deptno IN (SELECT deptno FROM emp);

SELECT @@optimizer_switch;

SET @@optimizer_switch='materialization=off'

SET @@optimizer_switch='block_nested_loop=off'

Derived Tables

SELECT job, SUM(sal) FROM emp


GROUP BY job
HAVING SUM(sal) > 5000;

SELECT job, total FROM


(SELECT job, SUM(sal) total FROM emp
GROUP BY job) AS t
WHERE total > 5000;

Transactions
Transaction is set of DML queries that is executed as a single unit. if any query from tx
fails, rest of queries are rollbacked (discarded).
Example

accid type ... balance


1 S 50000
2 S 1000

transfer 6000 from acc1 to acc2.

UPDATE acc SET balance=balance-6000 WHERE accid=1;


UPDATE acc SET balance=balance+6000 WHERE accid=2;

To avoid problem due to failure of one of the query

START TRANSACTION;
UPDATE acc SET balance=balance-6000 WHERE accid=1;
UPDATE acc SET balance=balance+6000 WHERE accid=2;
SELECT * FROM acc;
COMMIT;
-- or
ROLLBACK;

Example
CREATE TABLE dept (deptno INT PRIMARY KEY, dname VARCHAR(20));
INSERT INTO dept VALUES (10, 'DEV');
INSERT INTO dept VALUES (20, 'QA');
INSERT INTO dept VALUES (30, 'OPS');
INSERT INTO dept VALUES (40, 'ACC');
SELECT * FROM dept;

START TRANSACTION;
DELETE FROM dept WHERE deptno=30;
SELECT * FROM dept;
ROLLBACK;
SELECT * FROM dept;

START TRANSACTION;
DELETE FROM dept WHERE deptno=40;
SELECT * FROM dept;
COMMIT;
SELECT * FROM dept;

Note that, when COMMIT or ROLLBACK is done, current tx is completed. For further
changes start a new tx.

START TRANSACTION;
SELECT * FROM dept;
DELETE FROM dept WHERE deptno=30;
SELECT * FROM dept;

DROP TABLE dummy; -- auto-commited.

SELECT * FROM dept;


ROLLBACK; -- no tx to rollback

Tx is not applicable for DDL queries. If DDL query is executed within a tx, that tx is
auto-committed.

Savepoint
Savepoint is state of database stored temporarily within transaction.
To perform multiple operations within a tx safely, it is recommended to create
savepoints.
We can rollback to a savepoint, which ensure all work done till that savepoint is intact.
However in this case, tx is not yet completed.
When tx is completed (COMMIT or ROLLBACK) all savepoints saved so far will be
discarded.
Note that, COMMIT TO savepoint is not supported.
START TRANSACTION;

dml1;
dml2;
SAVEPOINT sa1;
dml3;
dml4;
SAVEPOINT sa2;
dml5;
dml6;

ROLLBACK TO sa2;

dml7;
dml8;
COMMIT;

Tx characteristics
RDBMS tx are ACID.

Atomic: Set of queries are executed as single unit. They cannot be committed
partially.
Consistent: At the end of tx, all users will see the same data.
Isolated: All tx execute independent of each other.
Durable: At the end of tx, final state of data is saved on disk (durable).

S-ar putea să vă placă și