SQL деректер базасын көпшілігі көптеген дизайн

Мен әр ойынға қатысатын ойыншыларды және әрбір ойыншыны сақтау үшін спорттық ойын негізінде дерекқорды жасаймын. Көптеген қарым-қатынастарға көптеген қиындықтарды шешіп жатырмын. Менде келесі кестелер бар:

Ойыншы

id
name

Матч

id
date

PlayerMatch

player_id
match_id
home_team
goals_for
goals_against

Матчта әрдайым екі ойыншы болады. Бұл көзқарас үшін бұл ең жақсы жоба ма?

0
Сіздің сұрағыңыз қандай?
қосылды автор Steven Wexler, көзі
Бір матчта тек бір ойыншы бар ма?
қосылды автор Math, көзі
Әдетте матчты екі команда (немесе ойыншылар) жасайды, сондықтан бұл жағдайда N-N қатынастары қажет болмайды.
қосылды автор Math, көзі
Мәселен, матчта екіден көп ойыншылар бар ма? BTW, ойыншы сіз команда немесе адам дегенді білдіресіз бе?
қосылды автор Math, көзі
Адам, бұл тек екі сәтте болады деп ойлаймын, бірақ қалайша көп өзгеретінін көре алмаймын?
қосылды автор Carl, көзі
Тек редакцияланған матчта әрқашан екі ойыншы болады
қосылды автор Carl, көзі

6 жауаптар

Көптеген қарым-қатынастарыммен байланыста болуды ұсынамын. Бұл деректер моделін күрделендірмей, қанша ойыншының оңай ойнауға болатындығының ерекшеліктерін өзгертуге мүмкіндік береді.

Ойыншы

id
name

Матч

id
date

PlayerMatch

player_id
match_id
is_home
goals_for
goals_against

Foreign key from PlayerMatch to Player
Foreign key from PlayerMatch to Match

    --All the matches a player has played in.
    SELECT m.* 
    FROM Player p
    JOIN PlayerMatch pm
        ON p.id = pm.player_id
    JOIN Match m
        ON m.id = pm.match_id
    WHERE p.id = /*your player Id*/

    --All the players in a match
    SELECT p.*
    FROM Match m
    JOIN PlayerMatch pm
        ON m.id = pm.match_id
    JOIN Player p
        ON p.id = pm.player_id
    WHERE m.id = /*your match Id*/

    --player information for a single match.
    SELECT pm.*
    FROM Player p
    JOIN PlayerMatch pm
        ON p.id = pm.player_id
    JOIN Match m
        ON m.id = pm.match_id
    WHERE p.id = /*your player Id*/
        AND m.id = /*your match Id*/
1
қосылды
Мен сіздерге көмектесетін жауапыма сұраныс қостым. Сондай-ақ, алғашқы екі сұрақтың біреуінде pm. * таңдай аласыз.
қосылды автор Steven Wexler, көзі
Сондықтан, home_team , содан кейін isHome
қосылды автор Steven Wexler, көзі
Жақсы, сондықтан көптеген-көптеген қатынастар пайдалы болады деп ойлаймын. Сондай-ақ, кейбір ойларды home_team , goals_for және goals_against түрінде енгізгіңіз келуі мүмкін. Егер ойыншылар командаларды ешқашан өзгертпесе, бұл өте маңызды мәселе. Алайда, ойыншыларға командаларды өзгерте алады деп күтемін :).
қосылды автор Steven Wexler, көзі
Спасибо, сенімдімін, әлі де екі ойыншымен ұстануға болады ма, немесе сіз айтқандай, ашық қалдыру туралы деректер базасында көп нұсқасын жазу.
қосылды автор Carl, көзі
Бұл шынымен командаға қатысты емес, бұл жай ғана жеке адам. home_team шынымен де маңызды емес, мен оны жоюға немесе оны home_player-ге ауыстыруға болар едім
қосылды автор Carl, көзі
Yep, SQL-дегі ойыншыға қатысты барлық матч туралы ақпаратты қалай аламын? мысалы, сондықтан менде күн, goals_for, goals_against, opposing_player_id бар
қосылды автор Carl, көзі

Көптеген-көпшіліктік қарым-қатынастарды пайдаланбайтын болар едім, бұны:

Ойыншы

id
name

Матч

id
home_player_id
guest_player_id
date
goals_home_player
goals_guest_player
1
қосылды
Ах, жеткілікті түрде оқымады :)
қосылды автор Steven Wexler, көзі
Түсініктемелерді оқыдым. Меніңше, ол кем дегенде екі ойыншыны айтты.
қосылды автор Steven Wexler, көзі
Бұл екі ойыншы үшін жақсы жұмыс істейді, бірақ ОС ойынға арналған ерекшеліктерді кеңейтуді қаласа, кеңейтілмейді.
қосылды автор Steven Wexler, көзі
Мен көремін ... бірақ ойын екі ойыншыдан артық ойнайтындығына сенімді емес еді. Мен қайта ойлаймын. Рахмет.
қосылды автор Math, көзі
Мен деп ойлаймын, бұл тек екі деп ойлаймын
қосылды автор Math, көзі

М Хагопианмен келісе отырып, оп схемасы жақсы бастамаға ұқсайды.

1
қосылды
қосылды автор Steven Wexler, көзі
Бұл жауап емес, түсінік болуы керек.
қосылды автор Steven Wexler, көзі
ОК, түсініктеме мен сілтеме үшін рақмет. Енді біреудің жауабына түсініктеме қосуды ғана білсем болады. :(
қосылды автор Steve D, көзі

Бұл жарамды опция, бірақ мен екі кестеде бірдей баған атауын пайдаланатын (яғни match_id Match және PlayerMatch ішінде, player_id үшін бірдей) қолданылатын атау конвенциясын ұсынамын. Бұл сіздің SQL-іңізді біраз түсінікті етуге және кейбір дерекқорларға (MySQL) қосылып жатқанда біріктірулер үшін 'using (col1, col2, ...)' синтаксисін пайдалануға мүмкіндік береді.

1
қосылды

Деректер қатынастарының мұндай түрі мүлдем табиғи емес. Оны орнату үшін өзіңізге екі сұрақ қойыңыз:

  • Ойыншылардың бірнеше матчтары бар ма?
  • Біреуден көп ойыншы бар ма?

Егер жауап екеуіне де иә болса, сізде көп-көпшілік қарым-қатынасыңыз бар, және бұл өте сирек кездеседі. Олардың орындалуы біршама қиындығы бар. Бір-біріне көп қатынаста, сіз кейбір кестеде жазбалардың тізіміне шетелдік кілт ұстап тұрасыз. Қалай болғанда да, бұл ойыншылар мен кестелер кестесінің жазбалардың кейбір тізбесіне шетел кілтін қажет ететін жағдайдан басқа көп-көпшілік қатынастарда қалай жұмыс істейтіндігі.

Бұл тізім Bridge Table деп аталады. Осылайша, қарым-қатынастан бас тарту үшін сіз жалпы үш кестені пайдалануыңыз қажет

Players
-------
player_id


Player_Match
------------
player_id
match_id


Matches
-------
match_id

Жоғарыдағы диаграмманың ортасында кесте көпір кестесі деп аталады және ол карта ойнатқыштардан сәйкестендіруге ештеңе жасамайды және ойындарды ойыншылардың тізіміне салыстырады. Жиі көпір кестелерінде тек 2 баған бар, олардың әрқайсысы көпірлі кестелердің біреуіне шетелдік кілт ұсынады. Көпірдің кестесінде бастапқы кілтдің қажеті жоқ, ал егер біреу болмаса, онда ойыншының сол матчтың біреуінен көп болуы мүмкін. Ойыншыда бір түрдегі матчтың тек біреуі болуы мүмкін болса, көпір кестесінің әр жолына арналған бастапқы кілтті бағандардың екеуінде де құрама кілт жасаңыз.

Дерекқорды жобалауда қалыпқа келтіру өте маңызды реляциялық мақсат болып табылады, себебі деректер базасы барынша икемділікпен және ең төменгі артықшылықпен қамтамасыз етеді. Қалыптастыру үшін, кестеге қойғыңыз келетін деректер - бұл бастапқы кілтпен сипатталған нысанның нақты төлсипаты. Мысалы, home_team матчтың нақты төлсипаты болып табылады. Жоқ, жоқ, жоқ. Бұл жағдайда, сіз Player_Match кестесінде home_team-ді «Командалар» кестесіне шетелдік кілтпен ауыстырыңыз. Матчтар кестесінде екі баған болуы керек. Біреуі үшін үй командасының шетелдік кілті, ал біреуі қонақтардың кілті үшін. Командалар матчтың шынайы белгілері емес және Match кестесін қалыпқа келтіру үшін сол деректерді өздерінің кестелеріне қойғыңыз келеді.

0
қосылды
Мен өзім ойлап тапқан дизайнымда өртедім. «Мақсаттар қойылды» - адамның нақты белгілері емес. Көптеген адамдар ешқашан ешқандай мақсат қоймады. Толық қалыпқа келтірілген дерекқорда бұл баған «мақсаттар» кестесіне шетелдік кілтпен ауыстырылады (күндер мен уақыттар тізімі қойылған). Ойыншылардың және Мақсаттар кестесінің арасындағы қарым-қатынасты пайдаланатын деректер базасында сұранысты орындау арқылы осы ойнатқыштың «қойған голдар саны» анықталуы мүмкін.
қосылды автор scottb, көзі

I think I'd try to model the match first & then see what happens with the table design :

Match
-------------
match_Id
player1_Id
player2_Id
player1_Goals
player2_Goals

Player1_Id және Player2_Id ойыншының үстеліне сыртқы кілттер де кіреді

Player
---------
Id
Name

Конвенциялық ойыншы1 әрдайым үй командасы болар еді

онда сіз оны сұрайтын боласыз

Select p1.name as player1_Home, p2.name as player2_away, 
matchId, 
player1_Goals as homeGoals, player2_Goals as awayGoals           
from Match m 
inner join Player p1 on p1.id = m.Player1_Id 
inner join Player p2 on p2.id = m.Player2_Id
0
қосылды