Permalänk
Medlem

Hjälp med databasstruktur

Håller på och gör en nyhetsbrevsfunktion till ett företag, men har inte hållt på jättemycket med databaser så jag är inte helt säker på hur jag ska lägga upp det hela.

Självklart har jag nyhetsbrev, mottagare och mottagarlistor i en varsin tabell, men sen blir det lite krångligare. T.ex. vill jag att mottagarna ska kunna tillhöra flera olika grupper, ska jag då spara vilka grupper som varje mottagare tillhör i någon sorts array i mottagartabellen eller lagra alla användare som tillhör en viss grupp i en array i den gruppen? Nackdelen med båda dessa är ju att man måste loopa igenom massa värden varje gång man ska komma åt dem. Är det då smartare att göra en till tabell som innehåller varje koppling mellan mottagare och mottagarlista?

Tänkte även lagra vilka mottagare som fått varje nyhetsbrev, så samma tänk ska väl appliceras där. Dock ska varje nyhetsbrev skickas till närmare tusen personer, om man då ska lagra varje koppling för sig, är det något man måste tänka på för att databasen inte ska bli slö?

Hur skulle ni ha gjort?

Tack på förhand!

Permalänk
Medlem

Du vill ha en many-to-many-tabell som knyter samman dina medlemmar med dina grupper.

Ponera följande tabeller:

[GROUP]
id
name

[MEMBER]
id
firstname
surname

[GROUPMEMBER]
group_id
member_id

Tabellen GROUPMEMBER är det magiska i sammanhanget då den knyter samman X medlemmar med Y grupper. Den har inget eget id utan använder både group_id (foreign key GROUP.id) och member_id (foreign key MEMBER.id) som en kombinerad primärnyckel.

För att visa alla grupper som medlem #42 är med i:

SELECT member.firstname, member.surname, group.name FROM member INNER JOIN groupmember ON (member.id = groupmember.member_id) INNER JOIN group ON (group.id = groupmember.group_id) WHERE member.id = 42;

eller för att visa alla medlemmar som är med i grupp #3:

SELECT member.firstname, member.surname, group.name FROM member INNER JOIN groupmember ON (member.id = groupmember.member_id) INNER JOIN group ON (group.id = groupmember.group_id) WHERE group.id = 3;

Enkelt och elegant

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Det där var ju till och med bättre än jag trodde det kunde bli, hade ingen koll på join. Tack så jäkla mycket!

Någon som vet en riktigt bra tutorial för hur man ska tänka när man bygger upp databaser? Gärna fokuserad på MySQL

Permalänk
Medlem

Upptäckte nu när jag provade det att jag får ut varje resultat två gånger av någon anledning, verkar lite konstigt.

Jag har tabellerna lists, recipients och knyter samman dem med listconrec

$test = mysql_query("SELECT recipients.id AS rec_id, recipients.name, recipients.mail, recipients.company, lists.id FROM recipients INNER JOIN listconrec ON (recipients.id = listconrec.recipient) INNER JOIN lists ON (lists.id = listconrec.list)") or exit(mysql_error()); while($row = mysql_fetch_array($test)){ foreach($row as &$es){ echo $es . ' '; } echo '<br />'; }

Så här blir resultatet:

1 1 Testperson Ett Testperson Ett test@ett.se test@ett.se Testett Testett 4 4 4 4 Testperson Fyra Testperson Fyra test@fyra.se test@fyra.se Testfyra Testfyra 1 1 2 2 Testperson Två Testperson Två test@två.se test@två.se Testtvå Testtvå 3 3 3 3 Testperson Tre Testperson Tre test@tre.se test@tre.se Testtre Testtre 2 2

Permalänk
Medlem
Skrivet av Apro:

Upptäckte nu när jag provade det att jag får ut varje resultat två gånger av någon anledning, verkar lite konstigt.

Jag har tabellerna lists, recipients och knyter samman dem med listconrec

$test = mysql_query("SELECT recipients.id AS rec_id, recipients.name, recipients.mail, recipients.company, lists.id FROM recipients INNER JOIN listconrec ON (recipients.id = listconrec.recipient) INNER JOIN lists ON (lists.id = listconrec.list)") or exit(mysql_error()); while($row = mysql_fetch_array($test)){ foreach($row as &$es){ echo $es . ' '; } echo '<br />'; }

Så här blir resultatet:

1 1 Testperson Ett Testperson Ett test@ett.se test@ett.se Testett Testett 4 4 4 4 Testperson Fyra Testperson Fyra test@fyra.se test@fyra.se Testfyra Testfyra 1 1 2 2 Testperson Två Testperson Två test@två.se test@två.se Testtvå Testtvå 3 3 3 3 Testperson Tre Testperson Tre test@tre.se test@tre.se Testtre Testtre 2 2

Jag tror det beror på att du använder mysql_fetch_array utan att specificera om du vill ha en associativ eller numrerad array. Detta innebär att din array innehåller bägge delar. Testa mysql_fetch_row istället, alternativt mysql_fetch_array( $sql, MYSQL_NUM ) som är samma sak.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Så enkelt var det, tack för hjälpen

Permalänk
Medlem

Nästa problem:

När jag redigerar en prenumerants uppgifter så representeras listorna av checkboxar som är markerade för varje lista som denne prenumererar på. Vilket sätt är det bästa att genomföra ändringar på dessa i databasen?
Ska jag loopa igenom listconrec och ta bort alla kopplingar till den prenumeranten och sen skriva dit de markerade listorna när jag trycker på spara, eller finns det något enklare sätt?
Att det inte blir flera kopplingar som är likadana är ju redan löst i.o.m. att recipient tillsammans med list är ett unikt värde, men vilket är det bästa sättet att ta bort en koppling när jag kryssat ur den checkboxen och tryckt på spara?

Permalänk
Medlem

Det enklaste måste väl vara att bara ta bort de kopplingar till listor som prenumeranten väljer bort..? Redundant att ta bort alla och sen lägga till vissa igen.

DELETE FROM listconrec WHERE user_id = [ett id] AND list_id NOT IN ([förbockad1], [förbockad2], [förbockad3] ... [förbockadN])

Queryn blir nåt sånt där för att göra sig av med det som INTE är förbockat

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem
Skrivet av Teknocide:

Det enklaste måste väl vara att bara ta bort de kopplingar till listor som prenumeranten väljer bort..? Redundant att ta bort alla och sen lägga till vissa igen.

DELETE FROM listconrec WHERE user_id = [ett id] AND list_id NOT IN ([förbockad1], [förbockad2], [förbockad3] ... [förbockadN])

Queryn blir nåt sånt där för att göra sig av med det som INTE är förbockat

Hur menar du nu? Det där kommer ju att fungera för att ta bort de som kryssats ur, men inte lägga till de jag kryssat i. Med andra ord måste jag ju fortfarande ta bort alla och lägga till de som är ikryssade.

Permalänk
Medlem
Skrivet av Apro:

Hur menar du nu? Det där kommer ju att fungera för att ta bort de som kryssats ur, men inte lägga till de jag kryssat i. Med andra ord måste jag ju fortfarande ta bort alla och lägga till de som är ikryssade.

Det beror på hur du lägger upp gränssnittet. Jag tänker att vyn enbart presenterar de listor som en prenumerant är med i, och att man går ur listor genom att bocka av de rutor som inte är intressanta. Om alla valmöjligheter ska visas får man en jäkla massa kryssrutor när det finns 20+ listor att väja mellan, fast det kanske aldrig blir så många iofs.

Om man ska kunna lämna och gå med i listor i en och samma vy måste man precis som du säger utföra två statements mot den; en INSERT och en DELETE. Om det går snabbast att rensa alla poster för en användare och lägga upp dem på nytt eller bara lägga till/ta bort de som skiljer är svårt att svara på.

Det finns en möjlighet i REPLACE men jag har inte luskat klart på den för tillfället.

Visa signatur

Kom-pa-TI-bilitet