ADR-003 Выбор схемы базы (Tokens & Proxies Data Store) [DRAFT]¶
Прокси-контракт если относится к токену (через "target_address) то нужно возвращать именно прокси, а не token.
Нюансы¶
collate="c"pg_trgmUSING gin (col gin_trgm_ops);
Проблемы:¶
- Проблема ilike поиск, занимает 700мс
- Насколько оправданы join-ы
- Foreign key на партиции надо или нет?
Виды запросов пользователей¶
- Получить токен по token.address + network и вернуть meta. Для отображения мета-информации о текущем токене.
- Поиск token по имени (name и/или symbol ) - ‘usdt’. ILIKE(%
%). Для актокомплита. - Дай мне “Адрес баланса” с метаданными токена по ilike name/symbol сортированные по верифицированности, и имени токена. Типовой запрос которым бегают пользователи, зависит от пользовательской нагрузки. По прокси сортировать не требуется. Нагрузка в пике 100 запросов в минуту.
Расчет нагрузки:¶
Желаемое время ответа 300ms-500ms. 4-5 тыс обменов в день. Каждый 30% делает обмен. 15 тыс клиентов в день. В среднем 4 поиска на обмен. 2 тыс в час в течении 8-ми часов. 30 минуту. В пике 100 в минуту.
Термины:¶
- “Адрес баланса” - адрес токена или прокси, в случае если для него не установлен прокси-адрес. В случае если установлен это прокси.
Сущность token¶
Хранит метаинформацию (иконки, макретинг) о токенах, их адресах, сеть.
У одного токена может быть несколько прокси которые на него ссылаются.
Количество - 2-3 млн.
Поля:
- id - uuidv7
- address - hexstring 42
- network - (1 из 6 сетей) string/enum
- is_verified boolean, верифицирован ли он в блокчейн эксплорере
meta attributes: - txid - создавамая транзакция - symbol nullable могут быть пустыми - name nullable могут быть пустыми - decimals nullable - creator (address) - created_at - updated_at - block_number - когда создался
Индексы:
- (address + network) - unique
Сущность proxy¶
Один прокси может ссылаться только на один token. На один token может ссылаться много proxy.
Количество - 5-6 млн.
- id
- address - адрес proxy
- name nullable - используется если у токена нет
- symbol nullable - используется если у токена нет
- decimals nullable
- network
- token_address nullable (он-же target_address, токен еще не появился умуте), может ссылаться на не существующий токен.
Индексы:
- (network, token_address)
- (network, ddress) - composite primary key, unique априори уникален
Один прокси только для одного адреса.
meta attributes: - proxy_type
Сущность "Адрес обмена" (композит)¶
- name - token.name || proxy.name
- symbol - token.symbol || proxy.symbol
- address - proxy.address || token.address
- decimals - proxy.decimals || token.decimals
Вариант 1 (tokens, proxies, balance_addresses)¶
Бенчмарк - https://github.com/safeblock-com/token-db-schema-selection
Вариант 2 (tokens + proxies в одной таблице)¶
Таблица contacts (общая, tokens + proxy)¶
Поля:
- id - uuidv7
- address - hexstring 42
- network - (1 из 6 сетей) string/enum
- is_proxy boolean
- proxy_type - string/enum (10 штук, пополняется редко) ['ip701', 'ip702', ..]
- targed_address foreign key uuidv7 optionl если это proxy - может меняться.
meta attributes:
- txid - создавамая транзакция
- symbol - citext
- name - citext
- decimals
- creator (address)
- created_at
- updated_at
- block_number - когда создался
Индексы:
- (address + network) - unique
На поиск пары¶
- address=a targed_address=nil is_proxy=false
- address=b targed_address=nil is_proxy=true
- address=c targed_address=a is_proxy=true
- address=d targed_address=nil is_proxy=false
Пользователь вводит получение пар между a и d.
Мы должны вернуть пару c-d
select * from contracts where network='binance' and (address='a' and not is_proxy) or (target_address='a' and is_proxy) order by is_proxy;
Поисковый¶
Поиск по адресу:¶
Ищет a мы возвращаем c
select * from contracts where network='binance' and (address='a' and not is_proxy) or (target_address='a' and is_proxy) order by is_proxy limit 1;
Индексы:
(network, address, is_proxy)(network, target_address, is_proxy)
Поиск по имени:¶
Ищет a мы возвращаем c
select * from contracts where network='binance' and (address='a' and not is_proxy) or (target_address='a' and is_proxy) order by is_proxy limit 1;
Индексы:
(network, name, is_proxy)