SQL Learning - Basic Course

concept

SQL is the abbreviation of Structured Query Language, which means "Structured Query Language". It generally refers to various SQL databases in the current computer, such as MySQL and Microsoft Server SQL.

  • The following statements are based on MySQL, and other databases may have slight differences in field types and syntax, but they are similar.

create

By create table [tableName] (Array<field>)creating a users table:

--  用户表
create table `User`
(
    id         integer primary key unique auto_increment comment '用户标识',
    username   varchar(20) not null unique comment '用户名',
    nickname   varchar(20)          default '' comment '昵称',
    sex        char(2)     not null default 0 comment '性别',
    age        char(2)     not null default 0 comment '年龄',
    authorId   integer comment '作者标识',
    createTime Datetime(3) default Datetime(3),
    updateTime Datetime(3) default Datetime(3)
);
-- 作者表
create table `Author`
(
    id       integer primary key unique auto_increment comment '作者标识',
    nickname varchar(20) unique comment '昵称',
    userId   integer not null,
    constraint `Author_userId_fkey` foreign key (userId) references `User` (`id`),
    state    char(1) default 0 comment '账号状态',
    category tinyint(50) comment '写作类型',
    level    tinyint(10) comment '级别'
);
-- 书籍表
create table `Book`
(
    id          integer primary key unique auto_increment comment '书标识',
    authorId    integer      not null,
    constraint `Book_authorId_fkey` foreign key (authorId) references `Author` (`id`),
    bookName    varchar(30)  not null unique comment '书名',
    description varchar(255) not null unique comment '描述',
    state       char(1) default 0 comment '书籍状态',
    readCount   integer default 0 '阅读量',
    create_time datetime(3) '上架时间'
        update_time datetime(3) '更新时间'
)
-- 书籍章节内容
create table `BookChapter`
(
    id        varchar(50) unique default uuid() comment '书籍章节标识',
    bookId    integer not null,
    constraint `BookChapter_bookId_fkey` foreign key references `Book` (`id`)
        chapterName varchar (50) not null unique comment '章节名称',
    state     char(1)            default 0 comment '章节状态',
    content   text               default '' comment '章节内容',
    readCount integer            default 0 comment '阅读量'
)
-- 订阅书籍,通过state:【0:互不关注,1:用户1关注用户2,2:用户2关注用户1,3:用户1和2互相关注】
create table `AuthorSubscribe`
(
    id      integer unique   default uuid() comment '订阅标识',
    fUserId integer not null,
    constraint `BookSubscribe_fUserId_fkey` foreign key (fUserId) references `Author` (`id`)
        sUserId integer not null,
    constraint `BookSubscribe_sUserId_fkey` foreign key (sUserId) references `Author` (`id`),
    state   char(1) not null default 0
)

foreign key

The foreign key is used to associate the relationship between two tables, such as between a teacher and a student, a teacher leads a group of students, so you need to set a foreign key in the student table to point to the teacher table, and then if you need to find a teacher to lead This association can be used to find all students of , or to find a student and its teacher.
The direct attachment of foreign keys was demonstrated when creating the table structure, and the foreign keys are added by additionally modifying the table as follows:

alter table `Author`
    add constraint `Author_userId_fkey` foreign key (`userId`) references `User` (`id`);

If it is only a foreign key of the database, it generally refers to a physical foreign key, but it can also be associated simply through code without relying on the database. This is called a logical foreign key.

  • Physical foreign key, using a foreign key to define a foreign key to associate with other tables, the advantage is that the relationship is all set in the database, and human errors will not easily occur. The disadvantage is that it affects the efficiency of adding, deleting, and modifying, and it is easy to cause deadlocks, and it is not suitable for scenarios such as distributed, cluster, and microservices.
  • Logical foreign key, only defines the association in the code, and all additions, deletions, modifications and queries need to be processed at this layer. The advantage is that it is easy to change and handle complex situations. The disadvantage is that it lacks direct association. Once a fish slips through the net, it will not be processed by the middle layer or directly operated. The database will be messed up.

Query

select * from [tableName]Query by statement

select *
from User;

It should be noted that at present, most enterprises do not allow direct use of number query, but require to write the column name, because the use
of number will first execute the lookup of which fields in the table, and then query according to these fields, the efficiency will be problematic, and secondly, if The update of the table structure will inadvertently leak sensitive information, which is not conducive to early detection of problems.

Add/insert data Create

insert into [tableName] values (Array<field>)Insert data by statement

Modify/update data Update

Pass statement update [tableName] set [field]=[value] where [condition]:

update `Author`
set penname='笔下留情'
where id = 1;

Delete data Delete

Pass statement delete from [tableName] where [condition]:

delete from `BookChapter` where id=1;

column query

The column query does not use the * number, but lists the specific field names to be queried. By select fieldName1, fieldName2 from [tableName]querying

select bookName, state
from Book;

column operation

Column query results support some simple operations or function usage

select bookName, create_time * 1000
from Book;

column alias

For the possibility of renaming some queried column names, it is common to query two tables at the same time, and both tables have the same name column name. In this case, one or both of them need to be renamed. You can use the or syntax
for renaming . If newFieldName1 conflicts with the table name or requires spaces, you can add single or double quotes 'new field name1'select fieldName1 newFieldName1 from [tableName]select filedName1 as newFieldName1 from [tableName]

select User.state user_state, Author.state author_state
from User,
     Author
where...

Deduplication

Sometimes there will be duplication of the column data in the query (note that the column name is duplicated in the front, and the data is duplicated here), and if duplication is not required, you can use distinct to modify the field to deduplicate

select username, distinct authorId
from User;

conditional query where

The corresponding row can only be output by specifying field values ​​that meet the requirements through conditional query, which can complete most of the daily requirements.
Conditional queries can be used according to the field type: >, >=, <=, != for comparison of single values, between…and, in, like, is null, and , or, not for range processing

To find those created or updated after 2023:

select *
from Book
where update_time >= '2023-01-01'
   or create_time >= '2023-01-01'

Find multiple titles with different keywords:

select bookName
from Book
where bookName in ('逆天', '邪神');

Find authors whose names end with:

select authorName
from Author
where authorName like '%番茄';

aggregate function

Aggregate functions can be sorted by columns (fields), including:

  • sum Computes the sum.
  • count counts the number of columns, ignoring columns with Null values
  • max Get the column with the maximum value
  • min Get the column with the minimum value
  • avg get the average value
select bookName,
       sum(readCount) as '总阅读数', count(readCount) as '总共书本量', max(readCount) as '单本最多阅读数', min(readCount) as '单本最少阅读数', avg(readCount) as '单本平均阅读数'
from Book
where state = 1;

Group query group by/having

The group query combines the query results into one row according to the requirements.
Contains group by field names and having filter conditions.
The following example is to group the user query results by gender and calculate the number of merged rows (that is, the number of gender)

select *, count(id)
from User
where sex!=Null
group by sex

having can be used to filter the grouping results after group by

select *, count(id)
from User
where sex!=Null
group by sex, name
having count (id) > 1

window function over

over is used to perform group by-like grouping on individual fields to return a result set.
Syntax: over (partition by [fieldName])

select id, name, avg(Book.id) over(parttition by Book.type)
from Author,
     Book
where Author.id = Book.authorId

Over can use order by to sort internally, but it will affect the evaluation result, so that the results of each row will only be sorted and calculated according to the previously queried rows:

  • Row 1, calculated according to Row 1
  • Line 2, calculated according to lines 1 and 2
  • Line 3, calculated according to lines 1, 2, and 3
  • ...and so on
  • Row n, calculated according to row 1, 2, ... n-1, n

Partition by can also be followed by special functions.
Available functions:

  • first_value(col)
  • last_value(col)
    serial number function:
  • rank() Returns according to the sorting, after multiple identical serial numbers, it will jump to the correct serial number, such as 1, 1, 3, 4, 4, 6
  • row_number() only returns the sequence number when the sorting values ​​are the same
  • dense_rank() When the sorting is the same, it does not jump the sequence number but follows it, such as 1, 1, 2, 3, 3, 4

Process control case

Process control statements can be used to output different content according to field values. For example, when gender is defined as integer or Boolean, more meaningful text male and female can be output in this way, which is equivalent to an alias processing of the value:

select (case sex
            when 1 then 'male'
            when 2 then 'female'
            else 'unknown' end
           ) sex,
       name
from User;

sort order by

Mainly ascending asc and descending desc, the default is ascending.

select *
from Book
order by update_time desc;

Multi-table joint query

By adding multiple table names after from, use where to specify the correct match. If no where filter condition is used, it will become a Cartesian product, which means the number of products of the number n of columns in the left table and the number m of columns in the right table. The number of rows, 5 records in the left table, 6 records in the right table, the result is 30 records:

select User.*, Author.*
from User,
     Author
where User.id = Author.userId;

connection query join

Join query can be performed by adding [join table name on condition] after the query statement, which can be subdivided into multiple types, and the default is left join:

  • Inner join, inner join, intersection, and row records between tables that can be matched by where will be displayed. When adding multiple tables after from, the inner join is actually used for query.
  • Left join, left outer join, left complete set, right intersection, all row records in the left table will be displayed, and the row records in the right table that are matched by where in the left table will be displayed, which is equivalent to even if the record queried in the right table is null Displayed because of the existence of the left table, the most commonly used one.
  • right join, right outer join, right full set, left intersection, and the opposite of the above. Records found in the right table will be displayed even if there is no suitable left table match.
  • full join, full connection, left and right complete sets.
select User.*, Author.*
from `User`
         join `Author` on `User`.`authorId` = `Author`.`id`

Joint query of three tables:

select User.*, Author.*, Book.*
from (User join Author where User.authorId=Author.id)
         join Book
where Author.id = Book.authorId

joint

Union is used to merge two query results. Note that the number of columns between the query results must be equal and the order must be paid attention to. Columns with the same order will be merged.
This feature is more commonly used when merging the results of multiple queries against the same table.

select id, author_name
from Author
         join User on Author.id = User.author_id and User.nickName = '逆天'
union
select id, author_name
from Author
         join Book on Author.id = Book.author_id and Book.update_time > '2023-01-01' 

subquery

By adding a statement that can be used as a separate query result to the statement and performing a secondary query, the condition part is called a subquery, and the other part is called a main query or an outer query.
Subqueries are mostly used after where, all available positions:

  • select
  • from
  • where
  • join

Queries can return results in many different forms, including:

  • scalar subqueries
  • column query
  • Row subquery (MySQL only)
  • table subquery

scalar subqueries

Only a single row and single column is returned in the subquery, and there is only one value, which can be directly matched by operators such as = and <=.

select *
from `User`
where `id` = (select userId as id from `Author` where nickname = '很爱很爱你')

column query

The subquery returns data in a single column, but contains multiple rows, and must be matched with in and not in ranges.
Note that if there is only one row of data, that is, a single column and a single row, it is called a scalar subquery.

select *
from `User`
where `id` in (select userId as id from `Author` where state = '1' or state = '2')

exist/in

exist/in are similar to find whether it exists in the collection range. If the subquery result has more records than the outer query, it is more efficient to use exist, that is:

  • Find less exists in many with exist
  • Find more exists in less using in

row subquery

A row and multiple columns are returned in a subquery, and operators such as = and <= can be used to directly match multiple columns.
Note that if there is only one column of data, that is, a single column and a single row, it is called a scalar subquery.
This is unique to MySQL.

select *
from `Author`
where (category, level) = (select category, level from `Author` where id = 1);

table subquery

The subquery returns multiple rows and multiple columns, similar to a double-table query, which is convenient for use as a temporary table. It is often used as a temporary table after from, or used with an in query after where.

Use as temp table:

select *
from (select * from `User` where createTime > '2023-01-01') u,
     `Author`
where u.id = Author.userId;

Use as collection scope:

select *
from `Author`
where (category, level) in (select category, level from `Author` where name like '鱼');

all/any

all/any can make the collection range into a single value for comparison of = operator, etc.:

  • all, so that the comparison process must satisfy all set values
  • any, so that the comparison process only needs to satisfy a set value

Correlation Queries/Temporary Tables/Intermediate Tables

The characteristic of the temporary table is that the subquery can actually perform interactive filtering with the data found in the main query, so that the results of the external query can be used when the subquery is filtered (where).
In the screening process, there is no obvious priority relationship, but the main and sub-queries are performed once and then filtered according to the conditions, such as:

select *
from employee
         join salary on salary.employee_id = employee.id
where salary.pay = (select max(salary.pay)
                    from salary
                    where salary.employee_id = employee.id)

public expression with

Common expressions are used to create statements whose query results can be used multiple times.
Syntax: with [name] (field1, field2) as (...SQL)
such as:

with user_q (id, name, author_id, email) as (*
from User, Author
where User.id = Author.user_id)
select *
from user_q;
select *
from author
where user_id in (user_q);

viewview

Views are used to create multiple query statements for one-time batch use, and are often used in statistical reports.
Syntax: create view [name] as (…SQL), such as:

create view user_author (id, name, author_id, email) as
(
select *
from User,
     Author
where User.id = Author.user_id);
select *
from user_author;

delete view

drop view [name];

It can only be used as a temporary table for update if it conforms to a simple view. Simple view rules:

  • no set operations
  • no distinct
  • No aggregation and analysis functions
  • no group by

Non-updatable means that when the view is used as a temporary table, the statement execution result cannot modify the query results before and after the view, which is convenient for restricting third-party modification.

Lock

Global lock/library lock

A global lock is to lock the entire database, using the following command to complete:

Flush
tables with read lock;

You can also consider using global variables:

set
global readonly=true;

This will make the entire library read-only, and writing to modify data and structures is not allowed. This method is generally only used for database backup or even not used.

table lock

Table-level locks lock single or multiple tables. Table-level locks in MySQL are divided into table locks and metadata locks.

Table locks can be restricted to read only or both read and write are prohibited:

-- 表锁
lock
/unlock tables table_name_1 read/write, table_name_2 read/write;

MDL metadata lock (Meta Data Lock) is automatically added when the sql statement is executed without explicit call. The sql for adding, deleting, modifying and checking will add MDL read lock, and the sql for modifying the table structure is prohibited; the sql for modifying the table structure will add MDL Write lock, which prohibits adding, deleting, modifying and querying sql.
MDL is specific to MySQL.

row lock

Row locks lock only one or more rows of data.
Row locks are generally implemented by database engines, and not all engines support them. They are commonly used in transactions:

begin;
update table_name_1
set value = value + 1
where name = 'a name';
delete
from table_name_2
where id = 1;
commit;

Gap Lock

Interval lock (Gap Lock) is a row lock in MySQL, which is used to lock a range instead of a single row. It locks a range, but not the records themselves, thus allowing other transactions to insert new records within the range, but not to insert records that already exist. Interval locks can prevent phantom reading problems, but will reduce concurrency performance.

Interval locks are automatically used in the following scenarios:
When querying with range conditions, MySQL automatically uses interval locks to prevent phantom reads.
For example:

SELECT *
FROM `table_name`
WHERE `id` BETWEEN 10 AND 20 FOR UPDATE;

Using interval locks manually:
Interval locks can be added manually using the following statement:

X lock/exclusive lock

SELECT *
FROM `table_name`
WHERE `id` BETWEEN 10 AND 20 FOR UPDATE;

or

S lock/shared lock

SELECT *
FROM `table_name`
WHERE `id` BETWEEN 10 AND 20 LOCK IN SHARE MODE;

Shared locks can coexist with another shared lock, but cannot coexist between a shared lock and an exclusive lock, or between an exclusive lock and another exclusive lock

Phantom reads and non-repeatable reads

– Phantom reading means that in the same transaction, due to the insertion of new data by other transactions, different result sets are returned under the same query condition.
– Non-repeatable read means that in the same transaction, due to data modification by other transactions, different result sets are returned under the same query condition.
– Both phantom reads and non-repeatable reads are problems in the transaction isolation level, but phantom reads are for insert operations, and non-repeatable reads are for modification operations.
– These problems can be solved by setting the transaction isolation level, such as setting the isolation level to Serializable.

Guess you like

Origin blog.csdn.net/u013102711/article/details/130478353