Մեսենջերի տվյալների բազան (հ․1): նախագծում ենք տվյալների կաղապարը

Ինչպե՞ս կարելի է բիզնես պահանջները փոխարկել կոնկրետ տվյալների կառուցվածքների, օրինակ, մեսենջերի «ցուցակային» նախագծման մեջ:

Մեսենջերի տվյալների բազան (հ․1): նախագծում ենք տվյալների կաղապարը
Մեր տվյալների база չի լինի այնքան մեծ և բաշխված, ինչպես VKontakte կամ Badoo, այլ «որ լինի», բայց լավ — գործառնական, արագ և տեղավորվի մեկ սերվերի վրա PostgreSQL — որպեսզի հնարավոր լինի ծառայության առանձին օրինակ բացել որտեղ-որ, օրինակ:

Ուստի չենք մտնի շարդինգի, կրկնության և աշխարհագրորեն բաշխված համակարգերի հարցերին, այլ կենտրոնանանք տվյալների բազայի ներքո սխեմայական լուծումների վրա:

Քայլ 1: Փոքր-ինչ բիզնես- specifiek

Մենք մեր հաղորդագրությունների փոխանակումը չենք նախագծում որպես抽象, այլ մենք इसे կցում ենք կորպորատիվ սոցիալական ցանցի. Ընդդիմադիր, մարդիկ մեզ մոտ չեն «կոտրվել», այլ շփվում են միմյանց հետ որոշակի բիզնես խնդիրների լուծման համատեքստում:

Ինչպիսի խնդիրներ են լինում բիզնեսում?.. Դիտենք օրինակ Վասիլի՝ ծրագրավորման վարչության ղեկավարի:

  • «Նիկոլայ, այս խնդրի համար պարաչ կա այսօր!»
    Նմանապես, հաղորդագրությունը կարող է կատարվել որոշ խնդրի համատեքստում գրքում.
  • «Կոլյա, գժվում ես երեկոյան Dota-ով»
    Այդպիսով, նույնիսկ մեկ զրուցակիցների զույգի միջև շփումը կարող է միանգամից լինել ոստիկանական տարբեր թեմաների շուրջ.
  • «Պետր, Նիկոլայ, նայեք կցվածներում նոր սերվերի գինը»
    Այդպես, մեկ հաղորդագրություն կունենա բազմաթիվ ընդունողներ. Այդ դեպքում հաղորդագրությունը կարող է պարունակել կցված ֆայլեր.
  • «Սեմեն, և դու էլ նայիր»
    Եվ անհրաժեշտ է, որ արդեն գոյություն ունեցող զրույցին նոր մասնակիցը հրավիրվի.

Թույլ տվեք դադարեցնել այս «արդիական» պահանջների ցուցակը:

Իրական հայտի և նրան պահանջվող սահմանափակումների ըմբռնելիս, արդյունավետ տվյալների բազայի սխեմա նախագծելը գործնականորեն անհնար է:

Քայլ 2: Կղզիային տրամաբանական սխեմա

Սխեմականորեն առայժմ ամեն ինչ նման է էլեկտրոնային հաղորդագրությանը՝ առկա գործիքի ստանդարտ գործիքը: Այո, «ալգորիթմիկորեն» բիզնեսի բազմաթիվ խնդիրները նման են միմյանց, ուստի դրանց լուծման գործիքները կառուցվածքային առումով նման կլինեն:

Նայենք արդեն ստացված տրամաբանական հարաբերությունների սխեմային: Օգնելու համար մեր մոդելը օգտագործենք ամենահիմնական տարբերակը ցուցադրման ER մոդել առանց UML կամ IDEF նոտացիաների բարդեցման:

Մեսենջերի տվյալների բազան (հ․1): նախագծում ենք տվյալների կաղապարը

Մեր օրինակով, մարմինը, փաստաթուղթը և բինարային «միավորում» են այս «արտաքին» գոյությունները, որոնք ինքնուրույն գոյություն ունեն և առանց մեր ծառայության: Ուստի, պարզապես ու ճանաչելու ենք նրանց իբրև որոշակի սոդեր «որտեղ-որ» թողնել UUID-ով:

Նկարեք սխեմաները հնարավորինս պարզ — մեծամասնությունը, ում դուք դրանք ցույց եք տալիս, չեն գիտակցում UML/IDEF-ի ընթերցում: Բայց — նա նկարեք պարտադիր:

Քայլ 3: Խոր-րդ կառուցվածքը

Սեղանի անունների ու դաշտերի մասինԴա, թե ինչպես ենք վերաբերվում «ռուհեր» տեսակի դաշտերին ու աղյուսակներին, կարող է տարբեր կերպ ընկալվել, բայց դա՝ առարկայի խնդիրը: Որպեսզի մեր «Թենզերում» ոչ մի օտար ծրագրավորող չկա, իսկ PostgreSQL-ն մեզ թույլ է տալիս անվանել թե թերագծերով, եթե դրանք ճանապարհված են մեջբերումներում, ուստի մենք նախընտրում ենք կոչել օբյեկտները պարզ ու հասկանալի, որպեսզի տարբեր մեկնություններ չառաջանան:
Որպեսզի հաղորդագրությունները մենք շատ մարդիկ միանգամից գրում են, մասամբ էլ նրանք կարող են անել դա օֆլայն ռեժիմում, ապա ամենադժվարագույն տարբերակը՝ ուրագործել UUID որպես ID-ներ ոչ միայն արտաքին էությունը, այլ նաև բոլոր օբյեկտները մեր ծառայության մեջ: Причем генерировать их можно даже на клиентской стороне — это поможет нам поддержать отправку сообщений при кратковременной недоступности БД, а вероятность коллизии крайне мала.

Մեր տվյալների բազայի նախնական կառուցվածքը կունենա այսպիսի տեսք՝
Աղյուսակներ : RU

CREATE TABLE "Թեմա"(
  "Թեմա"
    uuid
      PRIMARY KEY
, "Իրավիճակ"
    uuid
, "Վերնագիր"
    text
);

CREATE TABLE "Հաղորդագրություն"(
  "Հաղորդագրություն"
    uuid
      PRIMARY KEY
, "Թեմա"
    uuid
, "Լրագիր"
    uuid
, "ԱմսաթիվԺամանակ"
    timestamp
, "Տեքստ"
    text
);

CREATE TABLE "Հասցեատեր"(
  "Հաղորդագրություն"
    uuid
, "Մարդ"
    uuid
, PRIMARY KEY("Հաղորդագրություն", "Մարդ")
);

CREATE TABLE "Ֆայլ"(
  "Ֆայլ"
    uuid
      PRIMARY KEY
, "Հաղորդագրություն"
    uuid
, "BLOB"
    uuid
, "Անվանում"
    text
);

Աղյուսակներ : EN

CREATE TABLE theme(
  theme
    uuid
      PRIMARY KEY
, document
    uuid
, title
    text
);

CREATE TABLE message(
  message
    uuid
      PRIMARY KEY
, theme
    uuid
, author
    uuid
, dt
    timestamp
, body
    text
);

CREATE TABLE message_addressee(
  message
    uuid
, person
    uuid
, PRIMARY KEY(message, person)
);

CREATE TABLE message_file(
  file
    uuid
      PRIMARY KEY
, message
    uuid
, content
    uuid
, filename
    text
);

Ավելի հեշտ է ձևաչափը նկարագրելու ժամանակ՝ սկսելով «ներխուժել» կապի գրաֆիկից ապրանքների վրա, որոնք չեն մանրամասնում չնայած նրանք ոչ մեկին:

Քայլ 4՝ Որոնել ոչ ակնհայտ պահանջները

Վերջապես, մենք նախագծեցինք տվյալների բազան, որի մեջ կարելի է շատ լավ գրել և ինչ-որ ձևով կարդալ:

Եկեք մեզ դնենք մեր ծառայության օգտվողի տեղը՝ ինչ ենք ուզում անել նրա միջոցով

  • Վերջին հաղորդագրություններ
    Սա հրապարակված կարգով ոլորտային տարբեր նշաններով «իմ» հաղորդագրությունները: Երբ ես հասցեատեր եմ, երբ հեղինակ եմ, երբ ինձ գրել են, և ես չեմ պատասխանել, երբ ինձ չեն պատասխանել, ...
  • Ուղարկման մասնակիցներ
    Ո quiénParticipa en este largo largo chat, en realidad?

Մեր կառուցվածքն օգնում է լուծել այս երկու խնդիրները «ընդհանուր», բայց արագ՝ ոչ: Проблема в том, что для сортировки в рамках первой задачи անհնար է ստեղծել ինդեքս, որը համապատասխանում է յուրաքանչյուր մասնակցին (և ստիպված կլինենք ստանալ բոլոր գրառումները), իսկ երկրորդ համար անհրաժեշտ է ստանալ բոլոր հաղորդագրությունները մի թեմա:

Անհաշտ օգտվողի խնդիրները կարող են կարմիր թողնել արտադրողականությունը:.

Քայլ 5՝ 合理的 денормալизация

Մեր երկու խնդիրներն ոգեշնչելու են հավելյալ աղյուսակներ, որոնցում մենք պրկելու ենք որոշ տվյալներ, անհրաժեշտ է կազմել համապատասխան ինդեքսներ մեր խնդրում:
Մեսենջերի տվյալների բազան (հ․1): նախագծում ենք տվյալների կաղապարը

Աղյուսակներ : RU

CREATE TABLE "Հաղորդագրությունների Ռեեստր"(
  "Մտերիմ"
    uuid
, "Ռեեստրի Տիպ"
    smallint
, "Ամսաթիվ Ժամ"
    timestamp
, "Հաղորդագրություն"
    uuid
, PRIMARY KEY("Մտերիմ", "Ռեեստրի Տիպ", "Հաղորդագրություն")
);
CREATE INDEX ON "Հաղորդագրությունների Ռեեստր"("Մտերիմ", "Ռեեստրի Տիպ", "Ամսաթիվ Ժամ" DESC);

CREATE TABLE "Թեմայի Մասնակից"(
  "Թեմա"
    uuid
, "Հոգեբան"
    uuid
, PRIMARY KEY("Թեմա", "Հոգեբան")
);

Աղյուսակներ : EN

CREATE TABLE message_registry(
  owner
    uuid
, registry
    smallint
, dt
    timestamp
, message
    uuid
, PRIMARY KEY(owner, registry, message)
);
CREATE INDEX ON message_registry(owner, registry, dt DESC);

CREATE TABLE theme_participant(
  theme
    uuid
, person
    uuid
, PRIMARY KEY(theme, person)
);

Իսկ这里我们应用了两个典型的方法, применяемых при создании вспомогательных таблиц:

  • Ռեկորդների բազմապատկում
    Մենք ձևավորում ենք մեկ սկզբնական հաղորդագրության հիման վրա մի քանի հետևանքային գրառումներ տարբեր ռեესტրերում տարբեր սեփականատերերի համար՝ ինչպես ուղարկողի, այնպես էլ_RECEIVER-ի համար: Բայց այժմ յուրաքանչյուր ռեեստր թողնում է ինդեքս՝ որովհետև սովորաբար մենք կցանկանայինք տեսնել միայն առաջին էջը:
  • Ռեկորդների уникալизация
    Յուրաքանչյուր հաղորդագրություն ուղարկելու դեպքում կոնկրետ թեմայի շրջանակում բավարար է ստուգել, թե արդյոք արդյոք նման գրառում արդեն գոյություն ունի: Եթե ոչ՝ ավելացնենք այն մեր «լեքսիկոն»:

Հաջորդ մասում հոդվածը խոսելու է սեկցիոնավորման ներդրման մեր տվյալների բազայի կառուցվածքում:

Ընտանիք: habr.com

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster