Category Archives: MySQL
Protected: Show tables with LIKE and NOT REGEXP
MySQL: уровни изоляции транзакций
MySQL: уровни изоляции транзакций
Кто-бы ни купил MySQL, она еще долго будет будоражить ресурсы Наших с Вами серверов — и это хорошо.
Есть таблица
CREATE TABLE test (id INT, value VARCHAR(255)) ENGINE=InnoDB;
Что по Вашему покажет этот запрос?
START TRANSACTION;
INSERT INTO test(id, value) VALUES (1, 'test'), (2, 'test 2');
SELECT * FROM test;
COMMIT;
SELECT * FROM test;
А что покажет простейший SELECT во время выполнения текущей транзакции? Не ясно. Вот и придумали такие правила.
Первый READ UNCOMMITTED
Рассмотрим транзакцию выше. После INSERT данные сразу-же станут доступны для чтения. Тоесть еще до вызова COMMIT вне транзакции можно получить только что добавленные данные. В английской литературе это называется dirty read («грязное чтение»). Этот уровень редко используется на практике, да вообще редко кто меняет эти самые уровни.
Второй READ COMMTITED
В данном случае прочитать данные возможно только после вызова COMMIT. При чем внутри транзакции данные тоже будут еще не доступны.
Если рассмотреть транзакцию выше, то первый SELECT ничего не вернет, т.к. таблица у нас еще пустая и транзакция не подтверждена.
Третий REPEATABLE READ
Этот уровень используется по умолчанию в MySQL. Отличается от второго тем, что вновь добавленные данные уже будут доступны внутри транзакции, но не будут доступны до подтверждения извне.
Здесь может возникнуть теоретическая проблема «фантомного чтения». Когда внутри одной транзакции происходит чтение данных, другая транзакция в этот момент вставляет новые данные, а первая транзакция снова читает те-же самые данные.
И последний SERIALIZABLE
На данном уровне MySQL блокирует каждую строку над которой происходит какое либо действие, это исключает появление проблемы «фантомов». На самом деле смысла использовать этот уровень нет, т.к. InnoDB и менее популярный Falcon решают эту проблему.
Увидеть текущий уровень изоляции
SHOW VARIABLES LIKE '%tx_isolation%';
Установить
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Это всего лишь попытка вольного перевода самой обычной документации.
Спасибо.
Задачка:
CREATE TABLE one(id INT, value VARCHAR(12)) ENGINE = MyISAM;
CREATE TABLE two(id INT, value VARCHAR(12)) ENGINE = InnoDB;
START TRANSACTION;
INSERT INTO one (id, value) VALUES (1, 'test');
INSERT INTO two (id, value) VALUES (1, 'test');
ROLLBACK;
SELECT * FROM one;
SELECT * FROM two;
Что будет в первой таблице, а что во второй?
MySQL проектирование баз данных workbench mysql
https://www.visual-paradigm.com/download/
visual paradigm (php, java)
https://www.visual-paradigm.com/
Как в mysql лучше всего хранить ip адрес?
Как в mysql лучше всего хранить ip адрес? Varchar или int? По вашему мнению, бывают ли ситуации, когда нужно производить поиск по ip адресам, например ip > 127.0.0.1. Какие функции преобразование ip адреса есть в MySQL, а какие есть в php? Равнозначны ли они?
Наиболее удобно ip-адрес в MySQL хранить в типе INT. Причём обязательно UNSIGNED (беззнаковый), чтобы адреса выше 127. вполне вмещались в эти 4 байта.
1
|
`ip` int (10) unsigned NOT NULL |
Тип INT более удобен для хранения ip-адресов по сравнению с CHAR(15) по двум причинам:
- Требует меньше памяти (4 байта INT против 15 байт CHAR). Как результат, таблица занимает меньше места на диске, а скорость выполнения запросов возрастает, т.к. индекс меньшего размера.
- Удобно производить выборки по диапазонам адресов и маскам, а также делать сортировку (получается обычная сортировка по числам).
Имеется недостаток по сравнению с хранением ip как plaintxt (char или varchar) в mysql:
- Необходимость дополнительного преобразования ip-строки в число и наоборот для удобства восприятия. Для чего используются функции
INET_ATON
иINET_NTOA
(см. дальше). Но это ведь не проблема.
Как видно, достоинства хранения ip в UNSIGNED INT сильно превосходят единственный недостаток.
Функции преобразования ip-адреса в mysql:
- INET_ATON() — для преобразования IP адреса в число,
- INET_NTOA() — для обратного преобразования числа в IP адрес.
Для простоты запоминания нужно знать расшифровку аббревиатуры:
ATON
— Address TO Number (адрес в число),NTOA
— Number TO Address (число в адрес).
Примеры преобразования IP в mysql:
1
2
3
4
5
6
7
|
SELECT INET_NTOA(ip) FROM tablename LIMIT 10; # выведет ip в обычном строковом формате SELECT INET_ATON( '127.0.0.1' ); #2130706433 SELECT INET_ATON( '93.125.99.10' ); #1568498442 SELECT INET_NTOA(2130706433); #127.0.0.1 SELECT INET_NTOA(1568498442); #93.125.99.10 |
Аналогичные функции преобразования ip-адреса в PHP:
- ip2long() — для преобразования IP адреса в число;
- long2ip() — для обратного преобразования числа в IP адрес.
1
2
3
4
|
ip2long ( '127.0.0' ); //false ip2long ( '93.125.99.10' ); //1568498442 ip2long ( '127.0.0.1' ); //2130706433 ip2long ( '192.168.0.1' ); //3232235521 |
1
2
3
|
long2ip( '1568498442' ); //93.125.99.10 long2ip( '2130706433' ); //127.0.0.1 long2ip( '3232235521' ); //192.168.0.1 |
Задача. Нам нужно получить все записи, которые находятся в диапазоне адресов 148.100.0.0 — 158.255.255.255. Если хранить IP в виде строк, то пришлось бы производить поиск с помощью регулярных выражений, а запрос выполнялся бы очень долго.
В случае хранения IP-адреса в типе INT sql-запрос будет таким:
1
|
SELECT .... WHERE ip BETWEEN INET_ATON( '148.100.0.0' ) AND INET_ATON( '158.255.255.255' ) |
В случае хранения IP-адреса в виде строк sql-запрос будет таким:
SELECT …. WHERE INET_ATON(ip) BETWEEN INET_ATON(‘148.100.0.0’) AND INET_ATON(‘158.255.255.255’)