172 похожих чатов

Здравствуйте, товарищи. Возник интересный вопрос, на который не нашлось толкового

ответа.

Допустим планируется БД для некоторого мессенджера, похожего на Telegram

В этом мессенджере присутствуют такие штуки как юзеры, боты и конференции. У всех них есть юзернейм, который должен быть уникальным, т.е. один юзернейм не может быть назначен и юзеру и боту (так же как и боту и коефе, и юзеру и конфе).

Как такое выразить в схеме БД?


Самым простым решением пока что кажется ввести такую таблицу:

names:
username: str PK
user: int NULLABLE FK users.id
bot: int NULLABLE FK bots.id
conference: int NULLABLE FK conferences.id

И добавить ей триггер на вставку и обновление, проверяющий, соответственно что два из трёх полей user, bot, conference равны NULL

39 ответов

22 просмотра

если уж выделять отдеьлную таблицу то зачем вам на каждый тип сущности отдельное поле?

central hardware
если уж выделять отдеьлную таблицу то зачем вам на...

А как иначе? Инфа о юзерах, ботах и конференциях разнесена по разным таблицам, т.к. это всё разные сущности

Нейрофурран Гетероцикл
А как иначе? Инфа о юзерах, ботах и конференциях р...

так у вас в разных таблицах и будет ссылка на таблицу с username и все, из самого факта связи понятно что за сущность, нет?

central hardware
так у вас в разных таблицах и будет ссылка на табл...

Если из этих таблиц ссылаться на юзернейм то совершенно спокойно можно нарушить уникальность, сославшись из двух таблиц на один юзернейм. А мне необходимо такое исключить.

Можно и не триггер, а CHECK. А зачем вам разные нэймспейсы айдишников ботов и юзеров? По-моему, это тожэ путь к проблемам.

Да и конференцый тожэ. Без этого можно было бы сделать просто поле type.

Ilya Anfimov
Можно и не триггер, а CHECK. А зачем вам разные н...

Разные id'шники в целом не так уж критичны А вот с юзернеймами - беда

Нейрофурран Гетероцикл
Разные id'шники в целом не так уж критичны А вот с...

Ну, некритичны -- это ладно. Я спрашываю -- а зачем вообще так делать? От этого видно сразу несколько проблем (куча API должны будут получать id и тип, все акторы этих API должны будут смотреть в какие-то unionы таблиц) -- и не видно каких-то плюсов.

> И добавить ей триггер на вставку и обновление Для этого хватит и CHECK. > Как такое выразить в схеме БД? Ещё вариант — "перевернуть" предложенную схему, т.е. сделать: entity(username PK /* ну или использовать cуррогатный ключ, по сути это неважно*/ ); users(username FK entity, ...); bots(username FK entity, ...); conferences(username FK entity, ...); Тут нужен триггер для проверки того, что entity — это что-то одно (и, возможно, только одно).

Ilya Anfimov
Ну, некритичны -- это ладно. Я спрашываю -- а заче...

"Зачем так делать?" это про юзернеймы? Если да то в целом мне такое кажется весьма удобным. Т.е. юзернейм по сути служит некоторым алиасом. Про проблемы не совсем понял, можно подробнее?

Нейрофурран Гетероцикл
"Зачем так делать?" это про юзернеймы? Если да то ...

Это про разные id у ботов, пользователей и конференцый.

у выше упомянутого телеграмма id кстати по моему уникальные как минимум для чатов и юзеров

Yaroslav Schekin
> И добавить ей триггер на вставку и обновление Д...

В случае с переворотом, получается, при добавлении новой таблицы которая так же будет хранить информацию об "именованных" штуках потребуется переписывать все триггеры?

Yaroslav Schekin
> И добавить ей триггер на вставку и обновление Д...

И прямо в entity вписать (username, type), эту жэ пару использовать как FK. в таблицы users,bots,conferences вписать ещё CHECK (type=)

Нейрофурран Гетероцикл
В случае с переворотом, получается, при добавлении...

Если не выкручиваться каким-то образом, то да. Но и CHECK-и (ну или триггеры) в "Вашей" модели Вы тоже будете вынуждены менять в таком случае, кстати.

Ilya Anfimov
И прямо в entity вписать (username, type), эту жэ ...

Зачем? Так хочется нарушить 2NF на ровном месте? ;)

Yaroslav Schekin
Если не выкручиваться каким-то образом, то да. Но ...

Ну чисто субъективно выглядит проще поменять триггер/чек в одной таблице чем в нескольких

Ilya Anfimov
Чтобы не писать ни одного триггера.

Не писать ни одного триггера чтобы что?

central hardware
у выше упомянутого телеграмма id кстати по моему у...

В телеграме, емнип, id'шники юзеров и чатов различаются знаком Насчёт ботов - не знаю, не уточнял

Ilya Anfimov
Чтобы не писать ни одного триггера.

Зато придётся тупо писать 'bot' в каждую запись таблицы "bots" и т.д. (да и переименовывать таблицы, если что, тоже может быть проблематично), что не очень приятно. Но тут каждое решение не без недостатков, это да.

Ilya Anfimov
Это про разные id у ботов, пользователей и конфере...

Да в целом не видится страшным иметь в API разные эндпоинты для получения инфы о юзерах/ботах/конфах Наоборот было бы странно видеть один общий эндпоинт для всей своры

Нейрофурран Гетероцикл
Да в целом не видится страшным иметь в API разные ...

Получение инфы-то ладно. Она и правда сильно разная. Со списками сообщений и прочими линками/перепостами -- всё веселее.

Ilya Anfimov
Не придётся, там default будет.

Хранить придётся, я имел в виду (и это довольно тупо, IMNSHO). Но, опять-таки, тут каждое решение не без минусов.

Yaroslav Schekin
Хранить придётся, я имел в виду (и это довольно ту...

Это да. Что ещё хужэ -- потребуется дополнительный индэкс для fk entity, кроме pk.

Yaroslav Schekin
Зачем? Так хочется нарушить 2NF на ровном месте? ;...

Можно денормализовать не на пустом месте, если в таблице с юзернеймами так же хранить name, surname и title (первые - для юзеров, третье для ботов и конф), так как это существенно упростит поиск...

Ilya Anfimov
Получение инфы-то ладно. Она и правда сильно разна...

Для сообщений так же планирую разные таблицы Как минимум разделить личные сообщения и сообщения в конференциях, т.к. в конференциях ещё будет ролевая модель с разрешениями

Владимир Наумов
у бота есть токен

Который средство аутэнтификацыи и потому меняется по много раз за жызнь бота.

Владимир Наумов
у бота есть токен

Токен имеется и у юзеров (access token'ы же). Но вообще да, с токенами будет неприятно, т.к. придётся и их разделять... Больно, очень больно

Владимир Наумов
у бота есть токен

Хотя падажжи. У бота токен же только один. А значит его можно определить в таблицу bots и никаких проблем не будет.

Нейрофурран Гетероцикл
Токен имеется и у юзеров (access token'ы же). Но в...

Не знаю, я многоботовую базу не делал, только для одного бота одна база.

Нейрофурран Гетероцикл
Хотя падажжи. У бота токен же только один. А значи...

Ну и при том ботам можно сделать отдельный API, чем решится множество проблем

Нейрофурран Гетероцикл
Можно денормализовать не на пустом месте, если в т...

И это ещё добавит триггеров (для синхронизации этой информации). Кстати: > так как это существенно упростит поиск... или усложнит — зависит от того, какой именно поиск. Я к тому, что денормализация — это tradeoff (т.е. что-то в итоге работает хуже) — вопрос в том, что важнее.

Yaroslav Schekin
И это ещё добавит триггеров (для синхронизации это...

Синхронизация не понадобится Я подразумеваю не копировать информацию об имени/тайтле, а хранить её только этой таблице, вместо хранения раздельно в таблицах юзеров/ботов/конференций) А про поиск... Не думаю что селект по одной таблице будет сложнее и менее выгоднее селекта по сджоненным таблицам)

Нейрофурран Гетероцикл
Синхронизация не понадобится Я подразумеваю не коп...

> Синхронизация не понадобится А, ясно. > Не думаю что селект по одной таблице А зря (её размер-то тупо больше). Т.е. зависит от запросов, в любом случае ("JOIN-ы дорогие" и т.п. — это просто мифы). Кстати... вот посмотрел я ещё раз на оригинальную модель. Она же (грубо говоря) вот такая, правильно? CREATE TABLE users ( id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, other_stuff text ); CREATE TABLE bots ( id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, other_stuff text ); CREATE TABLE conferences ( id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, other_stuff text ); CREATE TABLE names ( username text PRIMARY KEY, "user" int REFERENCES users, bot int REFERENCES bots, conference int REFERENCES conferences, CHECK (num_nonnulls("user", bot, conference) = 1) ); Тогда что мне мешает сделать вот так, например INSERT INTO names(username, "user", bot, conference) VALUES ('username1', 1, NULL, NULL); INSERT INTO names(username, "user", bot, conference) VALUES ('username2', 1, NULL, NULL); ? Т.е. в ней тоже как-то не хватает constraints... нет?

Yaroslav Schekin
> Синхронизация не понадобится А, ясно. > Не дум...

Да, получается надо ещё навесить UNIQUE на user, bot и conference

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
вы делали что-то подобное и как? может есть либы готовые? увидел картинку нокода, где всё линиями соединено и стало интересно попробовать то же в ddl на lua сделать. решил с ч...
Victor
8
Ребят в СИ можно реализовать ООП?
Николай
33
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Карта сайта