{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "Максим Кузнецов: заметки с тегом database",
    "_rss_description": "Простыми словами о веб-разработке",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/maxkuznetsov.ru\/tags\/database\/",
    "feed_url": "https:\/\/maxkuznetsov.ru\/tags\/database\/json\/",
    "icon": "https:\/\/maxkuznetsov.ru\/user\/userpic@2x.jpg?1586398004",
    "author": {
        "name": "Максим Кузнецов",
        "url": "https:\/\/maxkuznetsov.ru\/",
        "avatar": "https:\/\/maxkuznetsov.ru\/user\/userpic@2x.jpg?1586398004"
    },
    "items": [
        {
            "id": "45",
            "url": "https:\/\/maxkuznetsov.ru\/all\/kak-uznat-obschiy-ves-bazy-dannyh-i-nayti-samye-tyazhyolye-tabli\/",
            "title": "Как узнать общий вес базы данных и найти самые тяжёлые таблицы",
            "content_html": "<p>Вес баз данных<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">SELECT table_schema AS &quot;Database&quot;, \r\nROUND(SUM(data_length + index_length) \/ 1024 \/ 1024 \/ 1024, 2) AS &quot;Size (GB)&quot; \r\nFROM information_schema.TABLES \r\nGROUP BY table_schema;<\/code><\/pre><p>Размер таблиц, включая отдельно данные и отдельно индексы.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">SELECT CONCAT(table_schema, '.', table_name),\r\n       CONCAT(ROUND(table_rows \/ 1000000, 2), 'M')                                    `rows`,\r\n       CONCAT(ROUND(data_length \/ ( 1024 * 1024 * 1024 ), 2), 'G')                    DATA,\r\n       CONCAT(ROUND(index_length \/ ( 1024 * 1024 * 1024 ), 2), 'G')                   idx,\r\n       CONCAT(ROUND(( data_length + index_length ) \/ ( 1024 * 1024 * 1024 ), 2), 'G') total_size,\r\n       ROUND(index_length \/ data_length, 2)                                           idxfrac\r\nFROM   information_schema.TABLES\r\nORDER  BY data_length + index_length DESC\r\nLIMIT  20;<\/code><\/pre>",
            "date_published": "2023-10-31T12:13:08+03:00",
            "date_modified": "2023-10-31T12:12:57+03:00",
            "_date_published_rfc2822": "Tue, 31 Oct 2023 12:13:08 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "45",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": []
            }
        },
        {
            "id": "18",
            "url": "https:\/\/maxkuznetsov.ru\/all\/db-acid\/",
            "title": "Базы данных, транзакции и ACID",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"https:\/\/maxkuznetsov.ru\/pictures\/acid2.jpg\" width=\"600\" height=\"266\" alt=\"\" \/>\n<\/div>\n<p><i>Транзакция<\/i> — набор команд, которые должны быть выполнены одной пачкой, так как представляют собой одну бизнес операцию.<\/p>\n<blockquote>\n<p>Пример: транзакция по переводу денег состоит из команд «списать деньги с отправителя», «начислисть деньги адресату».<\/p>\n<\/blockquote>\n<p><i>ACID<\/i> — это требования к транзакциям и системам, работающим с ними (например, базам данных). ACID требует, чтобы каждая транзакция<\/p>\n<ul>\n<li>не зависала в середине пути в случае ошибки, а откатывала все сделанные изменения (атомарность),<\/li>\n<li>после своего завершения не оставляла данные неконсистентными (консистентность),<\/li>\n<li>не влияла на другие транзакции (на самом деле влияла, но как можно меньше — 4 уровня изолированности),<\/li>\n<li>а вся система гарантировала, что выполненные транзакции будут запомнены системой даже при возникновении аварий и форс-мажоров (стойкость, durability).<\/li>\n<\/ul>\n<p><details><br \/>\n<summary>Подробнее о каждом требовании и с примерами<\/summary><\/p>\n<ol>\r\n<li>\r\n<b>Atomicity\/Атомарность<\/b> требует, чтобы либо все команды транзакции были выполнены, либо ни одной. То есть транзакция должна действовать как единая атомарная команда.\r\n<br\/><br\/>\r\nНа практике атомарность реализуется через версионирование и откаты (rollback) команд транзакции до первоначального состояния базы. Строго говоря, индексы могут обратно не откатиться, но чаще всего СУБД это разруливают сами.\r\n<\/li>\r\n<li>\r\n<b>Сonsistency\/Консистентность<\/b> требует, чтобы после завершения транзакции данные оставались консистентными и валидными, т. е. чтобы они не имели логических или технических противоречий.\r\n<br\/><br\/>\r\nПример: суммарный баланс счетов должен оставаться неизменным (логическая К.), запись одной таблицы не должна ссылаться на удалённый айдишник другой записи (техническая К.).\r\n<\/li>\r\n<li>\r\n<p><b>Isolation\/Изолированность<\/b> — при параллельном выполнении транзакции не должны влиять друг на друга. \r\n<\/p>\r\n<p>\r\nПример: если два человека одновременно делают денежный перевод третьему, то одна транзакция в теории может перезаписать значения другой, и деньги потеряются. Изолированность исключает такую ситуацию.\r\n<\/p>\r\n<\/li>\r\n<li><b>Durability\/Стойкость<\/b> — если транзакция завершена успешно, то она не может быть отменена даже при авариях, внезапном отключении света в датацентре и проблем в сети. В этом случае база данных должна сама восстановить последние транзакции.\r\n<\/ol>\n<h2>Уровни изолированности в базах данных<\/h2>\n<p>На практике изолированность сложна в реализации и сильно влияет на производительность системы. Поэтому базы данных могут работать с четырьмя уровнями изолированности (от меньшей надёжности к большей).<\/p>\n<ol>\r\n    <li>\r\n        <p><b>Read uncommitted<\/b> — позволяет избежать «потерянных обновлений», когда две транзакции обновляют одно и то же значение\/строку.<\/p>\r\n        <p>На этом уровне UPDATE-транзакции резервируют данные для себя и блокируют для других UPDATE-транзакций. Тем не менее, SELECT-запросы не блокируются и даже могут считать промежуточное состояние данных, возникающие между выполнением команд одной транзакции.<\/p>\r\n        <p>Пример: транзакция на перевод денег состоит из команды на списание денег с одного счёта и команды пополнения другого счёта. На момент изменения баланса счёта первой транзакцией вторая подобная транзакция встанет в очередь, пока данные не освободятся. Но SELECT-запрос может считать состояние, когда деньги списаны с одного счёта, но на второй ещё не зачислены.<\/p>\r\n    <\/li>\r\n    <li>\r\n         <p><b>Read committed<\/b> — то же, что выше + решает проблему чтения «грязных» состояний незавершённых транзакций. Большинство баз данных по умолчанию работает на этом уровне изолированности.<\/p>\r\n         <p>Однако если транзакция содержит две SELECT-команды и во время между ними другая UPDATE-транзакция успешно завершится, то результат этих SELECT-запросов может отличваться: один вернёт состояние до UPDATE-транзакции, второй — после. Важно, что это не «грязное» состояние, а чистое, после успешной транзакции.<\/p>\r\n    <\/li>\r\n    <li>\r\n         <p><b>Repeatable read (повторяемость чтения)<\/b> — оба пункта выше + гарантирует, что SELECT-запросы в рамках одной транзакции всегда будут возвращать один и тот же результат, даже если другие транзакции обновляют или удаляют эти же данные. <\/p>\r\n         <p>Транзакция блокирует все строки, затрагиваемые её командами, включая SELECT, а другие транзакции с SELECT-, UPDATE- и DELETE-запросами к этим данным ждут её завершения. Естественно, это сильно снижает скорость обработки транзакций базой данных.\r\n         <\/p>\r\n    <\/li>\r\n    <li>\r\n         <p><b>Serializable<\/b> — три пункта выше + исключает «фантомные чтения». <\/p>\r\n         <p>«Фантомное чтение» похоже на проблему с двумя последовательными SELECT-запросами одной транзакции, но возникает, когда между SELECT-запросами была выполнена именно вставка (INSERT). Пример: аггрегационные запросы SELECT SUM(), SELECT COUNT().\r\n         <\/p>\r\n         <p>Это максимальный уровень изолированности. При нём транзакции выполняются так, будто других параллельных транзакций не существует.<\/p>\r\n   <\/li>\r\n  <\/ol>\n<p><\/details><br \/>\n<br\/><\/p>\n",
            "date_published": "2020-04-09T00:34:00+03:00",
            "date_modified": "2020-04-10T15:15:05+03:00",
            "image": "https:\/\/maxkuznetsov.ru\/pictures\/acid3.jpg",
            "_date_published_rfc2822": "Thu, 09 Apr 2020 00:34:00 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "18",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/maxkuznetsov.ru\/pictures\/acid3.jpg",
                    "https:\/\/maxkuznetsov.ru\/pictures\/acid2.jpg"
                ]
            }
        }
    ],
    "_e2_version": 3559,
    "_e2_ua_string": "E2 (v3559; Aegea)"
}