ch
Feedback
Базы данных (Data Base)

Базы данных (Data Base)

前往频道在 Telegram

Базы данных (Data Base). По всем вопросам @evgenycarter

显示更多
8 110
订阅者
+124 小时
+37
+630
吸引订阅者
七月 '26
七月 '26
+52
在0个频道中
六月 '26
+49
在0个频道中
Get PRO
五月 '26
+81
在0个频道中
Get PRO
四月 '26
+56
在0个频道中
Get PRO
三月 '26
+85
在0个频道中
Get PRO
二月 '26
+92
在0个频道中
Get PRO
一月 '26
+82
在0个频道中
Get PRO
十二月 '25
+87
在0个频道中
Get PRO
十一月 '25
+137
在31个频道中
Get PRO
十月 '25
+101
在1个频道中
Get PRO
九月 '25
+178
在36个频道中
Get PRO
八月 '25
+159
在1个频道中
Get PRO
七月 '25
+197
在27个频道中
Get PRO
六月 '25
+215
在19个频道中
Get PRO
五月 '25
+201
在44个频道中
Get PRO
四月 '25
+227
在40个频道中
Get PRO
三月 '25
+202
在38个频道中
Get PRO
二月 '25
+176
在31个频道中
Get PRO
一月 '25
+230
在33个频道中
Get PRO
十二月 '24
+183
在34个频道中
Get PRO
十一月 '24
+188
在32个频道中
Get PRO
十月 '24
+192
在29个频道中
Get PRO
九月 '24
+250
在28个频道中
Get PRO
八月 '24
+137
在17个频道中
Get PRO
七月 '24
+139
在0个频道中
Get PRO
六月 '24
+176
在23个频道中
Get PRO
五月 '24
+169
在19个频道中
Get PRO
四月 '24
+161
在0个频道中
Get PRO
三月 '24
+202
在20个频道中
Get PRO
二月 '24
+178
在18个频道中
Get PRO
一月 '24
+289
在23个频道中
Get PRO
十二月 '23
+246
在25个频道中
Get PRO
十一月 '23
+246
在17个频道中
Get PRO
十月 '23
+266
在18个频道中
Get PRO
九月 '23
+247
在0个频道中
Get PRO
八月 '23
+192
在0个频道中
Get PRO
七月 '23
+185
在0个频道中
Get PRO
六月 '23
+223
在0个频道中
Get PRO
五月 '23
+217
在0个频道中
Get PRO
四月 '23
+309
在0个频道中
Get PRO
三月 '23
+282
在0个频道中
Get PRO
二月 '23
+168
在0个频道中
Get PRO
一月 '23
+175
在0个频道中
Get PRO
十二月 '22
+224
在0个频道中
Get PRO
十一月 '22
+174
在0个频道中
Get PRO
十月 '22
+321
在0个频道中
Get PRO
九月 '22
+380
在0个频道中
Get PRO
八月 '22
+295
在0个频道中
Get PRO
七月 '22
+538
在0个频道中
Get PRO
六月 '22
+569
在0个频道中
Get PRO
五月 '22
+891
在0个频道中
Get PRO
四月 '22
+3 160
在0个频道中
日期
订阅者增长
提及
频道
23 七月+1
22 七月+4
21 七月+3
20 七月+2
19 七月+3
18 七月+1
17 七月+1
16 七月+2
15 七月+1
14 七月+2
13 七月+1
12 七月+2
11 七月+1
10 七月+3
09 七月+4
08 七月+4
07 七月+1
06 七月+6
05 七月0
04 七月+2
03 七月+4
02 七月+2
01 七月+2
频道帖子
🏁До старта обработки миллиарда записей 3… 2… 1… клик Выбирайте не просто СУБД, а гоночный болид для работы с данными. ClickH
🏁До старта обработки миллиарда записей 3… 2… 1… клик Выбирайте не просто СУБД, а гоночный болид для работы с данными. ClickHouse® в облаке Selectel — машина, адаптированная под предельные нагрузки и сложные трассы. Отлично работает с векторными типами данных, эффективна в запросах для задач поиска семантического сходства, кластеризации или RAG. Под капотом — SSD-накопители стандарта NVMe, оперативная память DDR5 и процессоры Intel® Xeon®Gold и AMD EPYC™. Мощное железо для максимальной производительности вашей баз данных. Пройдемся по базе. Что вас ждет после запуска кластера ClickHouse в облаке Selectel? ⚡Скорость. Кластеры рассчитаны на хранение и быструю обработку даже петабайтов данных и обработку тяжелых аналитических запросов. ⚡Надежность. В Multi-AZ кластерах ноды размещены в разных дата-центрах, чтобы инфраструктура продолжила работу даже при отключении одного из узлов. ⚡Экономичный расход. Может выполнять запросы к данным, хранящимся в S3 в формате Iceberg, без их копирования. Это позволяет сократить расходы более чем в два раза по сравнению с использованием только локальных дисков. На вас — пилотирование, а обслуживание кластера забирает на себя Selectel. Ускорьте работу с базами данных в облаке Selectel: https://slc.tl/ywhx8 Реклама. АО "Селектел". erid:2W5zFJF5Fkm

2
🚨 Антипаттерн: Почему OFFSET убивает твою базу (и как делать пагинацию правильно) Привет! Если вы когда-нибудь реализовывали
🚨 Антипаттерн: Почему OFFSET убивает твою базу (и как делать пагинацию правильно) Привет! Если вы когда-нибудь реализовывали каталог товаров или ленту новостей, то наверняка писали запрос с LIMIT и OFFSET. Для небольших таблиц это работает отлично, но как только проект взлетает и данных становится много, база начинает задыхаться. Давайте разберем, почему так происходит и как это лечить. ❌ Как мы делаем обычно: SELECT id, title, created_at FROM articles ORDER BY created_at DESC LIMIT 50 OFFSET 100000; В чем подвох? База данных не умеет «магически» прыгать на 100 000-ю строку. Ей придется прочитать, отсортировать (если нет подходящего индекса) и отбросить первые 100 000 строк, чтобы вернуть вам всего 50. Чем глубже пользователь листает страницы, тем медленнее работает запрос. Нагрузка на CPU и диски растет экспоненциально. ✅ Как делать правильно: Вместо того чтобы говорить базе «пропусти N строк», мы говорим ей «дай мне 50 записей, которые идут сразу после последней записи, которую я уже видел». SELECT id, title, created_at FROM articles WHERE created_at < '2023-10-25 14:00:00' -- дата из последней записи на предыдущей странице ORDER BY created_at DESC LIMIT 50; Этот запрос мгновенно найдет нужное место по индексу (B-Tree) и прочитает ровно 50 строк. Никакой лишней работы! 🛠 Важный нюанс: Если поле created_at не уникально (две статьи вышли в одну секунду), предыдущий запрос может пропустить данные. Используйте уникальный «тайбрейкер» - например, id. В PostgreSQL это можно сделать очень элегантно с помощью кортежей (Row Values): SELECT id, title, created_at FROM articles WHERE (created_at, id) < ('2023-10-25 14:00:00', 10543) ORDER BY created_at DESC, id DESC LIMIT 50; (Не забудьте создать составной индекс: `CREATE INDEX idx_articles_created_id ON articles (created_at DESC, id DESC);`) 📌 Итог: • OFFSET / LIMIT: Ок для админок с небольшим трафиком и малым объемом данных (до ~10-50к строк). • Keyset Pagination: Must-have для бесконечных скроллов (infinite scroll), публичных API и таблиц на миллионы записей. 👇 Скинь ссылку на этот пост фронтендеру, который просит «просто добавить номер страницы» в API. А какой метод пагинации чаще всего используете вы в своих текущих проектах? Делитесь в комментариях! 📲 Мы в MAX #db 👉 @database_info
371
3
💡 Универсальная шпаргалка по SQL 📲 Мы в MAX #db 👉 @database_info+7
💡 Универсальная шпаргалка по SQL 📲 Мы в MAX #db 👉 @database_info
482
4
💡 Универсальная шпаргалка по SQL 📲 Мы в MAX #db 👉 @database_info
💡 Универсальная шпаргалка по SQL 📲 Мы в MAX #db 👉 @database_info
1
5
Немного юмора) 📲 Мы в MAX #db 👉 @database_info
Немного юмора) 📲 Мы в MAX #db 👉 @database_info
537
6
7 обязательных стратегий для масштабирования вашей базы данных 📲 Мы в MAX #db 👉 @database_info
7 обязательных стратегий для масштабирования вашей базы данных 📲 Мы в MAX #db 👉 @database_info
573
7
Антипаттерны JOIN-ов в SQL и как их избежать JOIN - мощная штука, но может легко превратиться в генератор тормозов и дублей.
Антипаттерны JOIN-ов в SQL и как их избежать JOIN - мощная штука, но может легко превратиться в генератор тормозов и дублей. Вот топ-4 ловушек: 1️⃣ Забыли условие соединения SELECT * FROM orders JOIN customers; Без ON это картезианское произведение - каждая строка первой таблицы умножается на все строки второй. Легко получить миллионы ненужных записей. ✅ Как избежать: Всегда указывай условие соединения. 2️⃣ JOIN по неиндексированным колонкам Если соединяешь большие таблицы по полю без индекса - готовься ждать. ✅ Как избежать: Добавь индекс на ключи соединения. CREATE INDEX idx_orders_customer_id ON orders(customer_id); 3️⃣ Фильтры в WHERE вместо ON -- Плохо FROM orders LEFT JOIN customers ON orders.customer_id = customers.id WHERE customers.region = 'EU'; LEFT JOIN превратился в INNER JOIN, потому что фильтр в WHERE отсекает NULL-строки. ✅ Как избежать: Фильтруй в ON, если хочешь сохранить LEFT JOIN: LEFT JOIN customers ON orders.customer_id = customers.id AND customers.region = 'EU'; 4️⃣ SELECT *** в сложных JOIN-ах Такая выборка тянет все колонки всех таблиц. Много лишних данных + риск коллизии имён колонок. ✅ Как избежать: Явно указывай нужные поля. 💡 Вывод: JOIN - как скальпель. В умелых руках ускоряет, в неумелых - режет производительность. Сохрани, чтобы не резануть базу не туда ✂️ 📲 Мы в MAX #db 👉 @database_info
619
8
🗄 Нормализация баз данных: от 1NF до 4NF Нормализация помогает правильно организовать данные, избавиться от дублирования и с
🗄 Нормализация баз данных: от 1NF до 4NF Нормализация помогает правильно организовать данные, избавиться от дублирования и снизить риск ошибок при обновлении таблиц. 🔹 Первая нормальная форма — 1NF Каждая ячейка содержит только одно атомарное значение. Нельзя хранить несколько товаров в одном поле — каждый товар должен находиться в отдельной строке. 🔹 Вторая нормальная форма — 2NF Таблица соответствует 1NF, а каждый неключевой столбец полностью зависит от всего составного первичного ключа. Данные о заказе и его позициях обычно разделяются на разные таблицы. 🔹 Третья нормальная форма — 3NF Устраняются транзитивные зависимости. Например, имя и регион клиента лучше хранить в таблице клиентов, а в заказе оставить только идентификатор клиента. 🔹 Нормальная форма Бойса — Кодда, BCNF Усиленная версия 3NF: любой столбец, от которого зависят другие данные, должен быть потенциальным ключом. 🔹 Четвёртая нормальная форма — 4NF Устраняет независимые многозначные зависимости. Например, навыки сотрудника и его проекты следует хранить в отдельных таблицах. ✅ Результат нормализации — меньше дубликатов, проще обновление данных и более предсказуемая работа базы. А до какой нормальной формы вы обычно доводите структуру БД? #базыданных #SQL #нормализация #database #программирование #разработка 📲 Мы в MAX 👉 @database_info
739
9
📲 Мы в MAX #db 👉 @database_info
📲 Мы в MAX #db 👉 @database_info
1
10
Почему индекс в PostgreSQL не всегда спасает Индексы - мощный инструмент, но не панацея. Иногда запрос с индексом работает медленнее, чем без него. Почему? 1️⃣ Маленькая выборка - да, полное сканирование - нет Если таблица маленькая (до нескольких тысяч строк), PostgreSQL может решить, что быстрее прочитать всё целиком, чем прыгать по индексу. EXPLAIN ANALYZE SELECT * FROM users WHERE status = 'active'; План покажет Seq Scan, и это не баг. 2️⃣ Индекс не помогает с функциями в WHERE Запрос вида: SELECT * FROM orders WHERE DATE(created_at) = '2025-08-12'; не использует индекс по created_at. Решение — переписать условие: WHERE created_at >= '2025-08-12' AND created_at < '2025-08-13' 3️⃣ Селективность Если по условию отбирается больше ~5–10% строк, индекс становится невыгодным — чтение с диска и так почти сплошное. 4️⃣ Статистика устарела PostgreSQL выбирает план по статистике. Если она старая - план может быть неэффективным. ANALYZE table_name; - и жизнь наладится. 💡 Вывод: Индекс - не магическая кнопка «ускорить». Следи за планами запросов (EXPLAIN), обновляй статистику и оптимизируй условия. Сохрани, чтобы не наступить на этот грабельный индекс 🚀 📲 Мы в MAX #db 👉 @database_info
848
11
Почему Redis такой быстрый (несмотря на однопоточность)? 🔹 Хранение в памяти Redis хранит все данные в оперативной памяти, г
Почему Redis такой быстрый (несмотря на однопоточность)? 🔹 Хранение в памяти Redis хранит все данные в оперативной памяти, где время доступа измеряется наносекундами, а не миллисекундами. 🔹 Однопоточный цикл событий Redis обрабатывает команды в одном потоке, избегая блокировок, гонок и переключений контекста. Благодаря мультиплексированию ввода-вывода он эффективно обслуживает тысячи одновременных подключений через цикл событий. 🔹 Оптимизированные структуры данных Redis предоставляет специализированные реализации списков, множеств, отсортированных множеств и хешей, оптимизированные для производительности и экономии памяти. 🔹 Эффективность ввода-вывода Redis использует лёгкий текстовый протокол RESP для обработки сетевого I/O и поддерживает конвейеризацию, позволяя клиентам отправлять несколько команд в одном запросе. 🔹 Скрипты на стороне сервера Встроенный движок Lua даёт возможность выполнять сложные многошаговые операции атомарно на сервере, убирая необходимость лишних сетевых запросов. ♻️ Сделай репост, чтобы помочь другим. 📲 Мы в MAX #db 👉 @database_info
891
12
Чем отличаются друг от друга блокировки баз данных? В управлении базами данных блокировки — это механизмы, которые предотвращ
Чем отличаются друг от друга блокировки баз данных? В управлении базами данных блокировки — это механизмы, которые предотвращают одновременный доступ к данным, обеспечивая их целостность и согласованность. Основные типы блокировок: 🔴Shared Lock: позволяет нескольким транзакциям одновременно читать ресурс, но не модифицировать его 🔴Exclusive Lock: позволяет транзакции как читать, так и модифицировать ресурс 🔴 Update Lock: используется для предотвращения взаимоблокировки, когда транзакция намеревается обновить ресурс 🔴 Schema Lock: используется для защиты структуры объектов базы данных 🔴 Bulk Update Lock: используется во время массовых вставок 🔴 Key-Range Lock: используется в индексированных данных для предотвращения фантомных чтений 🔴 Row-Level Lock: блокирует конкретную строку в таблице 🔴 Page-Level Lock: блокирует конкретную страницу (фиксированный блок данных) в базе данных 🔴 Table-Level Lock: блокирует всю таблицу 📲 Мы в MAX #db 👉 @database_info
1 039
13
🔒 Почему одна "невинная" транзакция может положить продакшн Классическая ситуация: разработчик открывает транзакцию, делает выборку, потом какой-то API-запрос наружу (например, к платёжному шлюзу), и только потом коммитит. Транзакция висит открытой 3-5 секунд вместо миллисекунд. Локально всё ок, тесты зелёные. В проде — деградация через пару часов. Что происходит под капотом в PostgreSQL (MVCC): 1. VACUUM не может убрать мёртвые строки. Пока жива хоть одна старая транзакция, движок обязан хранить все версии строк, которые теоретически могут быть видны в её snapshot. UPDATE/DELETE копится в виде dead tuples, автовакуум работает, но эффективность падает. 2. Table bloat. Таблица физически растёт, индексы разбухают, страницы всё реже помещаются в shared_buffers — растёт I/O, падает cache hit ratio. 3. xmin horizon не двигается. Это глобальная граница, до которой можно чистить старые версии. Одна зависшая транзакция держит её на месте для ВСЕЙ базы, а не только для своей таблицы. 4. Реплики страдают отдельно. На hot standby с hot_standby_feedback = on долгая транзакция на реплике заставляет primary тоже не вакуумить нужные строки — эффект расползается по кластеру. Как ловить: SELECT pid, now() - xact_start AS duration, query FROM pg_stat_activity WHERE state != 'idle' ORDER BY duration DESC LIMIT 10; Плюс idle in transaction — отдельная категория боли: транзакция открыта, а коннекшен вообще ничего не делает (забыли закоммитить/роллбэкнуть). Лечится через idle_in_transaction_session_timeout. Правило для сеньора: транзакция должна жить ровно столько, сколько нужно для консистентности данных — не больше. Любой сетевой вызов, любая тяжёлая бизнес-логика — только вне транзакции или в отдельном коротком шаге. #postgresql #databases #mvcc 📲 Мы в MAX #db 👉 @database_info
950
14
Индексы в PostgreSQL: Часть 1 — B-Tree Если ты создавал индекс в PostgreSQL по умолчанию, значит, это B-Tree. Но как он работ
Индексы в PostgreSQL: Часть 1 — B-Tree Если ты создавал индекс в PostgreSQL по умолчанию, значит, это B-Tree. Но как он работает и когда он реально полезен? Что это такое? B-Tree индекс — сбалансированное дерево поиска. PostgreSQL автоматически использует его для: =\` (равенство) > < >= <= (сравнения) BETWEEN LIKE 'abc%' (только префикс, без %abc%). Пример: CREATE INDEX idx_users_email ON users (email); SELECT * FROM users WHERE email = 'test@example.com'; Запрос не будет сканировать всю таблицу — он сразу пойдёт по дереву. Подводные камни: 1. Не работает для произвольных LIKE: LIKE '%abc%' → индекс не поможет. 2. Осторожно с функциями: WHERE LOWER(email) = 'abc' — индекс не используется. Нужен функциональный индекс: CREATE INDEX idx_users_email_lower ON users (LOWER(email)); 3. Многоколонковые индексы: Порядок важен. (a, b) используется при фильтре по a или по a AND b, но не только по b. Когда ставить? - Уникальные поля (email, username). - Часто используемые фильтры и JOIN-колонки. - Сортировки (ORDER BY created_at DESC). Вывод: B-Tree — твой “универсальный солдат”. Но не пихай его на всё подряд. Перед добавлением — смотри EXPLAIN (ANALYZE). Сохрани, чтобы не забыть! 📲 Мы в MAX #db 👉 @database_info
757
15
Как упростить работу с кластером через веб‑интерфейс OpenSearch Dashboards Присоединяйтесь к вебинару от Selectel, чтобы разо
Как упростить работу с кластером через веб‑интерфейс OpenSearch Dashboards Присоединяйтесь к вебинару от Selectel, чтобы разобраться на практике, как развернуть кластер СУБД OpenSearch в облаке за несколько минут и управлять им с помощью веб-интерфейса OpenSearch Dashboards. Узнаете, как легко настроить мониторинг, визуализировать данные и метрики, работать с бэкапами, управлять пользователями и доступами. 📍 Онлайн ⏰ 16 июля в 15:00 👤 Кому будет полезно: сисадминам, архитекторам, администраторам баз данных, бэкэнд-разработчикам, техлидам Регистрируйтесь ➡️ https://slc.tl/3po0z Больше мероприятий для ИТ-специалистов в канале @selectel_events. Подписывайтесь! Реклама. АО "Селектел". erid:2W5zFK5Svmo
712
16
Хотите узнать секрет оптимизации SQL-запросов? Очень важно понимать порядок выполнения. В SQL-запросе операторы выполняются в
Хотите узнать секрет оптимизации SQL-запросов? Очень важно понимать порядок выполнения. В SQL-запросе операторы выполняются в следующем порядке: 1. FROM / JOIN 2. WHERE 3. GROUP BY 4. HAVING 5. SELECT 6. DISTINCT 7. ORDER BY 8. LIMIT / OFFSET 📲 Мы в MAX #db 👉 @database_info
741
17
🧱 Антипаттерн: использование UUID как Primary Key без оглядки На первый взгляд, UUID — классный способ генерировать уникальн
🧱 Антипаттерн: использование UUID как Primary Key без оглядки На первый взгляд, UUID — классный способ генерировать уникальные идентификаторы: – не зависят от последовательности – удобны для распределённых систем – безопасны для внешнего экспонирования Но если ты просто заменишь SERIAL или BIGINT на UUID в качестве PK — жди сюрпризов: ❌ В чём подвох: – Производительность INSERT'ов резко падает: UUID случайные → нет locality → индекс (обычно B-Tree) постоянно фрагментируется – Индексы пухнут: UUID = 16 байт, BIGINT = 8 байт. Разница кажется небольшой, но на больших объёмах — это боль – Чтение медленнее: за счёт увеличенного размера индексов и меньшего кэш-хита ✅ Как избежать: 1. Если нет жёсткой необходимости в UUID — не используй их как PK 2. Нужен UUID? Сделай его вторичным индексом, а PK оставь автоинкрементным 3. Или хотя бы используй UUID v7 (новый стандарт с time-based префиксом) — он улучшает локальность по сравнению с v4 Пример: CREATE TABLE users ( id BIGSERIAL PRIMARY KEY, public_id UUID DEFAULT gen_random_uuid() UNIQUE, name TEXT ); → Внутри БД — быстрый BIGINT, → Для внешних API — UUID. Удобно и производительно. 📲 Мы в MAX #db 👉 @database_info
905
18
Что мощнее — S3 или локальные диски? Разбираем сценарии использования S3-хранилища в связке с Postgres Pro На вебинаре узнает
Что мощнее — S3 или локальные диски? Разбираем сценарии использования S3-хранилища в связке с Postgres Pro На вебинаре узнаете о лучших практиках эксплуатации в продакшн-средах. Эксперты Selectel и Postgres Pro разберут все: от резервного копирования через pg_probackup и S3 Selectel до хранения паркетных данных с Postgres Pro AXE и результатов TPC-тестов. Особенно интересно будет архитекторам, техлидам и всем, кто отвечает за надежность и экономику хранения данных. 📍 Онлайн ⏰ 14 июля в 12:00 Регистрируйтесь ➡️ https://slc.tl/hh3pe Больше мероприятий для ИТ-специалистов в канале @selectel_events. Подписывайтесь! Реклама. АО "Селектел". erid:2W5zFJxhbub
822
19
3 способа «убить» индекс в SQL Запрос тормозит. Индекс есть. Что пошло не так? Вот 3 способа, которыми ты уже мог его сломать
3 способа «убить» индекс в SQL Запрос тормозит. Индекс есть. Что пошло не так? Вот 3 способа, которыми ты уже мог его сломать: ▪︎ обернул колонку в функцию ▪︎ поставил wildcard % в начале LIKE ▪︎ допустил неявное преобразование типов База данных не может нормально использовать индекс по колонке, если сначала ей нужно эту колонку преобразовать. Главное правило: оставляй колонку “голой” в WHERE. 📲 Мы в MAX #db 👉 @database_info
896
20
🔴 Антипаттерн: игнорирование поведения NULL в SQL Когда ты пишешь WHERE column != 'value', ты можешь думать, что фильтруешь
🔴 Антипаттерн: игнорирование поведения NULL в SQL Когда ты пишешь WHERE column != 'value', ты можешь думать, что фильтруешь всё, что не равно 'value'. Но если в колонке есть NULL, такие строки выпадут из выборки. Почему? Потому что NULL != 'value' даёт… UNKNOWN, а не TRUE. ❌ Пример проблемы: SELECT * FROM users WHERE status != 'active'; Если status у кого-то NULL — он не попадёт в результат. Неочевидно, но критично. ✔️ Как избежать: 1. Явно учитывай NULL'ы: SELECT * FROM users WHERE status != 'active' OR status IS NULL; 2. Работай с COALESCE, если допустимо: SELECT * FROM users WHERE COALESCE(status, '') != 'active'; 📌 То же касается и =: NULL = 'value' → UNKNOWN 📌 Агрегации (COUNT, AVG`) тоже игнорируют `NULL — помни об этом при аналитике Вывод: NULL — не "ничего", а "неизвестно", и SQL строго это уважает. Не учитывая это, легко получить баг, который даже не заметишь сразу. 💡 Всегда проверяй поведение WHERE, JOIN и агрегатов с NULL. Пиши явный код, особенно в проде. Сохрани, чтобы не ловить баги на ровном месте. 📲 Мы в MAX #db 👉 @database_info
920