Если в двух словах
Выбор между
BYTE
и CHAR
зависит от кодировки и объема данных, которые вы собираетесь представлять в байтах. BYTE
фиксирует объем данных в байтах и идеален для однобайтовых кодировок, таких как ASCII
где каждому символу соответствует один байт. Так, VARCHAR2(10 BYTE)
вмещает любую комбинацию из десяти байтов. CHAR
же определяет количество символов, не учитывая их объем в байтах; выбрав VARCHAR2(10 CHAR)
, вы гарантируете пространство на 10 символов, независимо от их размера в байтах. Для иллюстрации вот простой SQL-пример:-- BYTE: сохраняет байты
CREATE TABLE bytewise (name VARCHAR2(10 BYTE));
-- CHAR: распределяет пространство с учетом количества символов
CREATE TABLE charwise (name VARCHAR2(10 CHAR));
Если
BYTE
обеспечивает компактность данных, то CHAR
гарантирует гибкость, позволяя сохранять символы различной ширины. Ваш выбор зависит от типов символов, которые вы планируете использовать.Детали при работе с UTF-8
Важно понимать последствия выбора типа данных при работе с многобайтовыми символами кодировки, такой как UTF-8, где один символ может занимать до 4 байтов.
BYTE
, это может привести к проблемам в системах, поддерживающих много языков. CHAR
будет более надежной опцией, так как он обеспечивает достаточное пространство для любого символа, независимо от его веса.Критерии для выбора между
BYTE
и CHAR
:BYTE
будет наилучшим выбором.CHAR
выигрывает, когда важна поддержка множества языков, это помогает предотвратить проблемы с несоответствием размера хранения.BYTE
может быть быстрее по сравнению с CHAR
из-за обработки меньшего объема данных, что делает его подходящим для приложений с высокими требованиями к производительности.BYTE
и CHAR
можно прочитать тут @sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤3👎1🔥1
Вроде мелочь, а вполне-таки реальный кейс
В общем, необходимо вносить в договор дату в формате: "30 мая 2099 г."
Эта дата хранится в БД, ее нужно просто подгрузить и нормально отформатировать.
Для этого можно обращаться к месяцу с помощью:
LOWER(DATENAME(month, @Tdate))
, однако в таком случае получается месяц в именительном падеже - "май".И тут полезно вспомнить, что форматирование даты с правильными склонениями месяца работает из коробки:
SELECT FORMAT(GETDATE(), 'dd MMMM yyyy', 'ru-RU')
-- 30 мая 2099
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33🔥11❤8🤯1
concurrently control
. При том, не только в БД, а везде где хоть что-то выполняется параллельно.Допустим есть пользователь, у него есть 100 денег на счету. Пользователь может их тратить, вы проверяете баланс
SELECT balance ...
, затем обновляете баланс при покупке UPDATE ... SET balance = ? WHERE ...
. И вот в счастливый день как-то так вышло, что приходят сразу 2 запроса на покупки для этого пользователя. Одна на 50 денег, вторая на 70. Одна из них должна быть отклонена, т.к. денег недостаточно. Но в результате получается что обе покупки прошли и у вас проблема, вы продали то, что не надо было. И это даже не видно по балансу пользователя. Как же?Это типичный
race condition
, обе транзакции сначала данные читают, потом локально что-то делают, потом что-то пишут.При конкурентном доступе к ресурсу подрались только на последнем шаге, транзакция которая начала обновлять данные позже сначала подождала завершение первой транзакции. А затем банально перезаписала баланс на тот который считала правильным сама —
lost update
аномалия.FOR SHARE
, FOR UPDATE
дополнения. Потому они кстати и задокументированы в разделе Explicit Locking@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
❤17👍9🔥4👎1
SQL_cheatsheet.png
971 KB
Шпаргалок по SQL много не бывает, так что держите, полезно освежить перед собеседованием
Здесь освещаются самые основные операторы, такие как
JOIN
, IN
, LIKE
, BETWEEN
, ORDER BY
, а также много всего ещёПользуйтесь)
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20❤10👍2🎉1
В рейтинг попали самые перспективные разработки в сфере генеративного искусственного интеллекта по ключевым категориям. Туда попали сразу две нейросетки от Яндекса — текстовая YandexGPT и мультимодальная YandexART. Также Яндекс вместе с Stability AI, Open AI, Google, Microsoft, Tencent и Baidu стал одной из 11 компаний со всего мира, которые разрабатывают более одного типа GenAI-моделей.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤5🔥3🤬1
Состоялся релиз мажорной версии открытого масштабируемого решения для кластеризации баз данных MySQL — Vitess 19.
В этой версии разработчики добавили улучшения, направленные на оптимизацию масштабируемости, производительности и удобства использования с базами данных.
Изменения и дополнения в Vitess 19:
«Следуя тенденции последних трёх лет, новая версия Vitess быстрее предыдущей во всех тестах, которые мы отслеживаем в Arewefastyet. Мы исправили несколько проблем с производительностью, доработали интерфейс и код», — пояснили разработчики, порекомендовав изучить документацию проекта и список исправлений.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🔥1
Как правильно подставлять значения из переменных / списков / словарей в SQL запрос в Python?
⏩ Лучше всего использовать SQL запросы с использованием параметров:
⏩ Какие преимущества приносит использование параметров?
— Защита от SQL-инъекций
— Правильное квотирование литералов в зависимости от их типа (пример со строками, пример с датами).
— Оптимизация — сокращение времени работы SQL запроса. Благодаря использованию параметров следующие шаги не выполняются при повторном запуске (зависит от БД):
— проверка синтаксиса SQL запроса
— проверка прав доступа к объектам БД
— построение плана выполнения SQL запроса
— Защита от переполнения/вытеснения кеша SQL запросов. Например "безобидный" запрос
⏩ Пример использования параметров в SQL запросе:
При таком подходе можно использовать
📎 Читать подробнее
@sqlhub
cursor.execute("SELECT * FROM my_table WHERE id = ?", [123])
# parameter placeholder ------------------------> ^
# список/кортеж со значениями параметров -----------> ^^^^^
— Защита от SQL-инъекций
— Правильное квотирование литералов в зависимости от их типа (пример со строками, пример с датами).
— Оптимизация — сокращение времени работы SQL запроса. Благодаря использованию параметров следующие шаги не выполняются при повторном запуске (зависит от БД):
— проверка синтаксиса SQL запроса
— проверка прав доступа к объектам БД
— построение плана выполнения SQL запроса
— Защита от переполнения/вытеснения кеша SQL запросов. Например "безобидный" запрос
qry = f"SELECT first_name, last_name FROM users WHERE id = {user_id}"
, который часто выполняется в нагруженной системе с различными значениями user_id
может вытеснить из кеша запросов полезные запросы. import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table lang (name, first_appeared)")
cur.execute("insert into lang values (?, ?)", ("C", 1972))
lang_list = [
("Fortran", 1957),
("Python", 1991),
("Go", 2009),
]
cur.executemany("insert into lang values (?, ?)", lang_list)
cur.execute("select * from lang where first_appeared=:year", {"year": 1972})
print(cur.fetchall())
con.close()
При таком подходе можно использовать
cursor.executemany()
- это значительно быстрее и эффективнее по сравнению с вставкой в цикле по одной строке.@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤3🔥2😁1
BEGIN
, COMMIT
, ROLLBACK
.BEGIN
и завершается командой COMMIT
(успешное завершение) или ROLLBACK
(откат). Указывать BEGIN
, COMMIT
и ROLLBACK
не обязательно, часто их использование подразумевается неявно. В случае если сессия неожиданно прерывается, тогда все транзакции, которые были начаты в текущей сесcии – автоматически откатываются.—
BEGIN
– инициирует новую транзакцию. После выполнения этой команды все последующие операции с базой данных будут выполняться в рамках этой транзакции.—
COMMIT
– завершает текущую транзакцию, применяя все её операции. Если все операции в транзакции были успешными, результаты этих операций фиксируются (становятся постоянными). Изменения становятся видны последующим транзакциям.—
ROLLBACK
– откатывает текущую транзакцию, отменяя все её операции, если в процессе выполнения транзакции возникли ошибки или отмена транзакции производится приложением исходя из внутренней логики работы.COMMIT;
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25❤4🔥3
- Проблема: Выбор всех столбцов с помощью
SELECT *
приводит к передаче ненужных данных, увеличению использования памяти и снижению производительности запросов.- Решение: Укажите в операторе SELECT только необходимые столбцы.
-- Пример проблемы
SELECT * FROM employees;
-- Улучшенный запрос
SELECT employee_id, first_name, last_name FROM employees;
- Проблема: Отсутствие индексов может привести к полному сканированию таблицы и снижению производительности запросов.
- Решение: Создайте и используйте индексы для часто используемых в выражениях WHERE столбцов.
-- Создание индекса
CREATE INDEX idx_last_name ON employees(last_name);
-- Использования индекса в запросе
SELECT * FROM employees WHERE last_name = 'Smith';
- Проблема: Подзапросы могут работать медленнее, чем JOIN, особенно при работе с большими наборами данных.
- Решение: Используйте JOIN, когда это возможно, а подзапросы оставьте для ситуаций, в которых они более эффективны.
-- Пример проблемы (подзапрос)
SELECT department_name FROM departments WHERE department_id IN (SELECT department_id FROM employees);
-- Улучшенный запрос (JOIN)
SELECT DISTINCT d.department_name FROM departments d JOIN employees e ON d.department_id = e.department_id;
- Проблема: Выбор неправильного типа JOIN (например, Cartesian JOIN) или неправильное указание условий соединения может привести к неправильным результатам или замедлению запросов.
- Решение: Разберитесь в различных типах JOIN (INNER, LEFT, RIGHT, FULL) и используйте их по назначению.
-- Пример проблемы (Cartesian JOIN)
SELECT * FROM employees, departments;
-- Улучшенный запрос (INNER JOIN)
SELECT e.employee_name, d.department_name FROM employees e
INNER JOIN departments d ON e.department_id = d.department_id;
- Проблема: Отсутствие фильтрации данных с помощью выражений WHERE может привести к запросу ненужных данных.
- Решение: Всегда включайте выражения WHERE, ограничивающие набор результатов.
-- Пример проблемы (без выражения WHERE)
SELECT * FROM orders;
-- Улучшенный запрос (с выражением WHERE)
SELECT * FROM orders WHERE order_date >= '2023-01-01';
- Проблема: Игнорирование планов выполнения запросов может привести к упущенным возможностям оптимизации.
- Решение: Используйте такие инструменты, как EXPLAIN, для анализа планов выполнения и внесения необходимых оптимизаций.
-- Просмотр плана выполнения
EXPLAIN SELECT * FROM products WHERE category = 'Electronics';
- Проблема: Запросы, хорошо работающие с небольшими наборами данных, могут плохо работать с большими объёмами данных.
- Решение: Реализуйте такие стратегии, как пагинация, разбиение данных на разделы и оптимизация индексов для больших наборов данных.
-- реализация пагинации
SELECT * FROM products LIMIT 10 OFFSET 20;
- Проблема: Повторение одних и тех же агрегаций в нескольких частях запроса может быть неэффективным.
- Решение: Используйте CTE (Общие табличные выражения) для хранения промежуточных результатов и избегайте лишних вычислений.
-- Пример проблемы (повторяющаяся агрегация)
SELECT department, SUM(salary) AS total_salary FROM employees GROUP BY department;
-- Улучшенный запрос (с CTE)
WITH DepartmentSalaries AS (
SELECT department, SUM(salary) AS total_salary FROM employees GROUP BY department
)
SELECT * FROM DepartmentSalaries;
- Проблема: Неправильная обработка ошибок может привести к сбоям в работе приложения или неправильным результатам.
- Решение: Реализуйте надлежащую обработку ошибок в SQL запросах или в коде приложения.
-- Пример обработки ошибок в SQL (MySQL)
BEGIN;
-- SQL выражение
IF some_condition THEN
ROLLBACK; -- Откат транзакции при ошибке
ELSE
COMMIT; -- Коммит транзакции при успешном выполнении всех выражений
END IF;
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40❤9🔥5👎2
Представьте, что у вас есть несколько таблиц Postgres, с которыми вам нужно работать и обрабатывать данные из таблиц с помощью Pandas по расписанию.
Как вы можете этого добиться?
Kestra, orchestrator проект с открытым исходным кодом, который поможет вам без особых усилий организовать этот рабочий процесс, используя файл
https://pypi.org/project/kestra/
@sqlhub
Как вы можете этого добиться?
Kestra, orchestrator проект с открытым исходным кодом, который поможет вам без особых усилий организовать этот рабочий процесс, используя файл
YAML
.https://pypi.org/project/kestra/
@sqlhub
❤10🔥3🤔2👍1
Временные таблицы в SQL обеспечивают удобный способ разбиения сложных задач на более мелкие и управляемые. Они позволяют разделить этапы обработки данных, что может повысить производительность, улучшить читаемость кода и упростить логику запросов.
CREATE TABLE
с ключевым словом TEMPORARY
или TEMP
перед именем таблицы:CREATE TEMPORARY TABLE temp_table (
id INT,
name VARCHAR(50),
age INT
);
Что тут происходит:
— Инструкция
CREATE TEMPORARY TABLE
используется для создания временной таблицы.—
temp_table
— это имя, которое присваивается временной таблице. Имя можно выбрать любое.— Внутри круглых скобок мы определяем столбцы временной таблицы.
— В данном примере временная таблица
temp_table
имеет три столбца: id
типа INT
, name
типа VARCHAR(50)
и age
типа INT
.— При необходимости мы можем добавить дополнительные столбцы, указав их имена и типы данных.
— Временная таблица автоматически удаляется в конце сеанса или при завершении сеанса.
Допустим, у нас есть большой набор данных, и мы хотим выполнить сложный анализ или вычисления на меньшей части этих данных. Для такого анализа можно создать временную таблицу, содержащую только необходимые строки и столбцы.
-- Создать временную таблицу с подмножеством данных
CREATE TEMPORARY TABLE subset_data AS
SELECT column1, column2, column3
FROM original_table
WHERE condition;
-- Анализ подмножества данных
SELECT column1, AVG(column2) AS average_value
FROM subset_data
GROUP BY column1;
-- Удалить временную таблицу
DROP TABLE subset_data;
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16👍9🔥3
💎 Квантизация нейросетевых моделей
Интересная статья, в которой ML-разработчик Яндекса рассказывает, что такое квантизация и как она помогает экономить ресурсы, разбирает типы данных и объясняет, что квантизовать, чтобы улучшить эффективность модели.
Автор также рассказывает, что такое выбросы, как они портят жизнь ML-инженерам, а также как с ними бороться.
📎 Статья
@sqlhub
Интересная статья, в которой ML-разработчик Яндекса рассказывает, что такое квантизация и как она помогает экономить ресурсы, разбирает типы данных и объясняет, что квантизовать, чтобы улучшить эффективность модели.
Автор также рассказывает, что такое выбросы, как они портят жизнь ML-инженерам, а также как с ними бороться.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3😁2🔥1
В статье показано, как с помощью matching в Oracle #SQL найти серию последовательных строк с начальной даты и до конечной:
MATCH_RECOGNIZE (
...
PATTERN (str e+)
DEFINE e AS start_date = PREV(end_date) + 1 --start is 1 day after previous end
)
https://how2ora-en.blogspot.com/2023/01/how-to-check-if-row-is-continuation-of.html@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3🔥2
Скажем, вам необходимо реализовать систему рассылки пуш-уведомлений на android-устройства клиентов. Вы пишете сервис, который будет работать с FCM. Пишете функции в вашей БД, которые будут выдавать списки token-текст (да там много полей вообще).
Так вот, необходимо, чтобы такие ручки для разных модулей (бэкендов) лежали в отдельных схемах.
Предположим, что вы реализовали пункт выше, теперь ваш сервис должен подключаться к БД и крутить свои запросы. Но под каким пользователем? Не будет же он бегать под
postgres
или admin
?)PostgreSQL — это мощная СУБД. Но и она не может быть универсальной. Не надо полагать, что всё делается штатными средствами PostgreSQL. Так-же не надо пробовать писать свои системы чего-либо.
Возьмите за привычку в БД всегда хранить
timestampTZ
и когда-нибудь Вам скажут большое спасибо за это.Так-же рекомендую сразу установить расширения для мониторинга запросов (например
pg_stat_statements
)PostgreSQL всегда временные таблицы кладёт на диск, это займёт много времени. Используйте табличные выражения. Да и лучше всё писать одним оператором.
Да да, секции — это круто. Но вот их использовать я бы рекомендовал только в некоторых случаях
Да, когда планировщик не так представляет выхлоп — у вас могут получиться очень медленные запросы.
Наверное сразу стоит добавить и тот пункт, что не надо хранить в
TOAST
( например json/text
с дефолтным параметром хранения ) аналитические данные.@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤5🔥1🤔1
Функции, которые вы ожидаете от IDE, работают прямо в вашем терминале". Среди этих функций:
- Каталог данных: просмотр таблиц, столбцов и их типов.
- Редактор запросов.
- Окно для отображения результатов (возможность вывода 1M+ записей).
- Экспорт результатов и история запросов.
▪Github
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤2🔥2🤔2🥰1
— Внутри базы создается отдельный счетчик, который привязывается к каждой таблице
— Счетчик увеличивается на единицу при вставке новой строки
— Получившееся значение записывается в поле, которое помечается как автогенерируемое
++
.GENERATED AS IDENTITY
:CREATE TABLE colors (
-- Одновременное использование и первичного ключа и автогенерации
id bigint PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
name varchar(255)
);
INSERT INTO colors (name) VALUES ('Red'), ('Blue');
SELECT * FROM colors;
-- id name
-- 1 Red
-- 2 Blue
Если удалить запись с
id
равным двум и вставить еще одну запись, то значением поля id
будет 3
. Автогенерация не связана с данными в таблице. Это отдельный счетчик, который всегда увеличивается. Так избегаются вероятные коллизии и ошибки, когда один и тот же идентификатор принадлежит сначала одной записи, а потом другой.column_name type GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY[ ( sequence_option ) ]
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🔥5👍2👎2🥰2
Отличная статья, в которой обсуждаются:
UNION
, INTERSECT
, EXCEPT
)Common Table Expression
, CTE (WITH)
WINDOW
/ OVER
)GROUP BY
)FROM
)JOIN
) и выражения подзапросов@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤5🔥3🎉1