Ik heb een db model gemaakt voor mijn website en nu vroeg ik me af of mijn model een beetje goed is hoe ik de relaties leg enzo... http://xs330.xs...del735.png
Paar opmerkingen...
Tabel: catogory Veld: catogory_type geeft weer of het een catogory is voor links of voor blogs, later komen hier dan weer meer types bij voor downloads bijvoorbeeld.
Tabel: tag Veld: tag_type hetzelfde als principe als bovenstaande.
Tabel: post Veld: blog_id wanneer blog_id = 0 dan is het een post in het gastenboek.
Tabel: post Veld: user_id wanneer user_id = 0 dan is het een post gemaakt door een gast. En word naam, email, website dus uit de tabel 'guest' gehaald.
Dat was het eigenlijk wel over me model.
Nu nog een ander vraagje, ik wou in me systeem dus ook een rechten systeem inverwerken. Nu wou ik hiervoor Zend_Acl voor gebruiken. Alleen heb ik een vraagje hiervoor ik wou nu graag de rechten in de db zetten. Nu had ik begrepen dat je zeg maar bepaalde rollen maakt en vervolgens geef je op waar die rol overal toegang tot heeft.
Je hebt dus bijvoorbeeld gebruiker Pietje. Pietje heeft de rol 'Staf' (samen met nog 5 andere personen) nu heeft hij de rechten om nieuws toe te voegen. Nu wil ik echter ook nog graag dat 'Pietje' ook toegang krijgt tot 'nieuws verwijderen' zonder dat ik daarvoor een aparte rol voor moet maken.
Nu is mijn vraag hoe zet ik hetgene wat ik wil om in me database model?
Het ziet er erg goed uit! Alleen zie ik een paar dingen die ik anders zou doen:
- De tabel posts1 moet die niet guests oid heten?
- Hoe kan een guest nu een post plaatsen? In de tabel posts staat alleen een verwijzing naar user_id en niet naar guest_id.
- Je prefixt alle kollomnamen (behalve fk's) met de tabelnaam. Dat zou ik zelf niet doen omdat je zo van die lange namen moet gebruiken als je gaat joinen in een query. user.id vind ik zelf beter staan dan users.user_id. Maar als jij het zo duidelijker vind moet je dat gewoon laten staan.
- De count velden (in verschillende tabellen), wat moet daar in komen te staan? Ik neem aan hoe vaak het voorkomt of geklikt is? Die bij blog is volgens mij overbodig omdat je ook een count in sql kunt halen over je blogtag tabel. Bij links weet ik het niet, maar als je nog gaat uitbreiden met een tabel van wie er op een link heeft geklikt heb je volgens mij net als bij blogtag die kolom count niet meer nodig.
- Bij blog zou ik de edit opslitsen in een blogedit tabel, zodat je ook later op kunt zoeken hoe vaak, wanneer een door wie een post allemaal is bewerkt.
- Bij blog zou ik die allow velden weg laten en ombouwen naar je acl systeem, dan kun je er ook veel meer mogelijkheden aan maken.
Over dat acl: een extra rol aanmaken voor Pietje is toch niet erg? Dat doen ze in dat artikel wat je postte ook. Je kan via acl ook een parent meegeven zodat de rechten worden overgeërfd vanaf een hogere rol.
In jouw geval zal die hogere rol dan de staff zijn. Om geen problemen te krijgen met groep en user namen die door elkaar raken kun je in het script waarin je de gegevens uit de database omzet naar een acl object ook de groepnamen prefixen met group_ oid.
Edit:
Even wat enters bijgezet, anders is het zo'n lap tekst achter elkaar.
Ja dat klopt. Dacht dat ik dat had maar blijkbaar niet.
Citaat:
- Hoe kan een guest nu een post plaatsen? In de tabel posts staat alleen een verwijzing naar user_id en niet naar guest_id.
Jawel kan wel want namelijk zoals ik zei bij me comment wanneer de post gedaan is door een gast zal de user_id = 0 zijn waarna ik vervolgens de gegevens uit de 'guest' tabel haal door de post_id met elkander te vergelijken.
Citaat:
- Je prefixt alle kollomnamen (behalve fk's) met de tabelnaam. Dat zou ik zelf niet doen omdat je zo van die lange namen moet gebruiken als je gaat joinen in een query. user.id vind ik zelf beter staan dan users.user_id. Maar als jij het zo duidelijker vind moet je dat gewoon laten staan.
Ja daarvoor heb ik gekozen omdat ik het graag erg duidelijk wil hebben zodat andere het later gewoon in 1 opslag kunnen zien wat ik zeg maar aan het doen ben.
Citaat:
- De count velden (in verschillende tabellen), wat moet daar in komen te staan? Ik neem aan hoe vaak het voorkomt of geklikt is? Die bij blog is volgens mij overbodig omdat je ook een count in sql kunt halen over je blogtag tabel. Bij links weet ik het niet, maar als je nog gaat uitbreiden met een tabel van wie er op een link heeft geklikt heb je volgens mij net als bij blogtag die kolom count niet meer nodig.
Ja die count rijen heb ik erbij gedaan puur om te tellen zodat ik geen COUNT() queries hoef uit te voeren om bijvoorbeeld dan te achterhalen hoeveel comments er al op een blog zijn geplaatst. Maar dit kan eventueel wel weg maar zover ik weet kunnen COUNT queries wel zwaar zijn voor de db daarom dat ik dus count rijen had aangebracht. Of valt dat opzich wel mee? Misschien dat iemand een grens weet?
Citaat:
- Bij blog zou ik de edit opslitsen in een blogedit tabel, zodat je ook later op kunt zoeken hoe vaak, wanneer een door wie een post allemaal is bewerkt.
Dit zal ik toevoegen.
Citaat:
Bij blog zou ik die allow velden weg laten en ombouwen naar je acl systeem, dan kun je er ook veel meer mogelijkheden aan maken.
Hmmm dit snap ik niet helemaal, wat ik niet snap is hoe je dit zou willen ombouwen naar het ACL systeem? Ik wil namelijk dat je dus per blog kunt bepalen of een gast die mag lezen ja of nee dus lijkt me ook toch het handigste deze gegevens in dezelfde tabel te zetten toch? En hiervoor zou je inprincipe dan geen Acl nodig hebben? Iig ik snap niet helemaal hoe ik Zend_Acl hierbij zou kunnen gebruiken. Namelijk bijvoorbeeld je hebt dan de role 'view' en dan zou je weer een subrole(s) moeten hebben die je toestaat om dat ID te lezen? Of begrijp ik het verkeerd?
En bedankt voor je reactie
-edit- ik heb trouwens ook nog een vraag, ik vroeg me af hoe websites bepalen of er gerelateerde nieuws-/blogberichten zijn aan een nieuws-/blogbericht? Ik dacht eerst gewoon even doordat ze gewoon nog een tabel hebben met het 'bericht_id1' en 'bericht_id2' en dat dus alle gerelateerde berichten in een select veld selecteren ofzo maar dit lijkt me toch zeer onwaarschijnlijk? Dus nu zat ik te denken dat websites daar een berekening voor die relatie hebben die kijkt naar bv catogorie en tag? Iemand misschien een linkje naar een tut/artikel hierover? Heb zelf namelijk niet veel kunnen vinden via google.
Ik dacht dat omdat je ook naar acl vroeg dat je gelijk van plan was dat grootschalig te gaan gebruiken. In dat geval zou je efficiënter in je database kunnen opslaan wie wat mag zien en bewerken enzo.
Het handige aan acl is dat je door overerving en algemene sets regels niet altijd voor elke resource en role een nieuwe regel op hoeft te stellen. Zo kan je in plaats van blog_allow_view_guest en blog_allow_guest_comment het zo opslaan.
Role - Resource - Option - Toestaan
null - null - null - false (standaard niets toestaan)
null - null - view - true (standaard weergeven toestaan)
guest - blog - view - true (gasten blog laten)
guest - blog - comment - false (gasten mogen geen comments plaatsen bij blog)
guest - blog_id_xx - view - false (gasten mogen blog post xx niet zien)
Als je het op zo'n manier in je database zet en ophaalt en in een acl object verwerkt kun je dan opvragen of guest blog xx mag zien. De acl houdt met alle regels op de juiste manier rekening en geeft terug of het mag of niet.
Cachen kan hierbij veel in performance schelen omdat het onnodig is om steeds alle regels op te halen als er toch niets is veranderd.
Ik denk dat het uiteindelijk sneller zal zijn om COUNT() te gebruiken. Zeker als je een index op het te tellen veld zet moet dat sneller gaan dan elke keer die teller updaten. Dat moet eigenlijk wel nog gecontroleerd worden hoeveel dat scheelt.
Ok bedankt voor je uitleg maar als ik het goed begrijp krijg ik dan straks in de db ook steeds voor iedere blog dus twee extra resources erbij. Namelijk of gasten mogen blog mogen zien ja of nee en of gasten mogen commenten ja ofwel nee.
Hetzelfde geldt dan trouwens voor de members? Want daarvoor staat die blog_comment (mogen users posten) en blog_status (publish leesbaar voor members of niet publishen alleen admin momenteel)
Iemand misschien nog een paar toevoegingen wat ik eventueel erbij zou kunnen verwerken bij blog systeem?
-edit-
Laatste versie van me model. http://xs130.xs...del711.png
Paar dingetjes veranderd. Belangrijkste wat mensen mss niet 123 snappe is denk ik post_parent? Dit heb ik zodat ik later een reactie opmaak kan doen zoals je op tweakers.net ziet.
Oh en ik heb nu van BlogTags TagsKey gemaakt waarin dan ook tag_type instaat (zie startpost) zodat ik die tabel kan gebruike om blogs, links, downloads te linken met een tag. Nu vroeg ik me af is dit de juiste manier? Of kun je beter gewoon 3 tabellen nemen?
-edit2-
Sorry voor me bump weer maar ik las net iets op een forum en nu viel er weer een vraag binnen maar bij de tabel post, catogory en role heb ik allemaal parents maar kan ik hier niet beter meteen foreign keys van maken aangezien ze verwijzen naar de primary key van dezelfde tabel? Of is dat zinloos?
Kun je me btw dat nog even uitleggen van het bovenstaande want ik snap eigenlijk de logica nog eigenlijk niet zo goed van want je gaat toch niet ook nog voor iedere blog bij de resources een rij toevoegen om te bepalen of de gast 1. blog mag zien en 2. mag commenten? *Blink* Of bedoel je dat je alleen de blog_id's toevoegt waarvan de gast ze niet mag zien en de blog_id's toevoegt welke hij niet mag op commenten? En als natuurlijk het eerste geld is het tweede van toepassing dus zal 'view' altijd boven 'comment' staan?
ps. nog even belangrijk stukje bold gemaakt omdat ik iedereens mening waardeer
Wat je vroeg over gerelateerde artikelen opzoeken daar heb ik ook nog even naar gezocht. Volgens mij doen andere sites dat ook door tags bij een artikel te zetten of te zoeken naar keywords en die als tags te gebruiken. Als ze dan een gerelateerd artikel willen vinden kijken ze welke artikelen de meeste tags gelijk hebben. Een script hiervoor heb ik nog niet kunnen vinden.
Post_parent gebruik je dan als iemand op een knopje "reageer op deze post" klikken toch? Dan krijg je zo'n boomweergave die je ook wel op youtube ziet volgens mij. Bij tweakers noemen ze het zoals je het op sitemasters ziet de flat mode en die andere nested mode.
Waar tags aan gekoppeld zijn is zo wat handiger op te slaan allemaal in één tabel, maar je moet dan wel ergens hardcoded een lijstje hebben met tag_type's.
Hoe je acl erin hebt gezet klopt niet helemaal volgens mij. Jij doet nu net alsof een resource een rule is. Je hebt roles (users of groepen users), resources (plaatsen waar op een bepaalde manier toegang toe is), options (wat je met een resource kan doen, zoals post, edit, view, publice, archive) en met een rule komt het allemaal samen. Daarin geef je een bepaalde combinatie van een role en resource en een option toestemming of juist niet. Daarbij kun je ook één of meer van de role/resource/option leeglaten om een algemene regel op te stellen.
Ik denk dat het voor jou handig is om in de tabel resources een record te zetten voor het blog, de links en de downloads. Als je er dan gelijk een id bij zet kun je dat ook weer koppelen aan je tagskey tabel. Als je daarin het veld tag_type hernoemt naar resource_id en er een foreign key van maakt is het helemaal duidelijk.
Idd jammer dat er niet meer mensen op dit topic reageren. Het zijn best lappen tekst die je moet lezen om er in te komen, maar het is toch interessant om zo tot de perfecte database structuur te komen!
Je zou bijvoorbeeld nog een extra functionaliteit in kunnen bouwen waarmee je de gebruikers in een groep kan indelen en deze vervolgens kan koppelen aan bepaalde 'roles'. Verder zie ik weinig knelpunten in het ontwerp. Misschien kan je nog wat verder normaliseren.
Het wordt trouwens niet aangeraden om tijdens het maken van je database model nog dingen bij te gaan verzinnen. Je moet namelijk eerst gaan brainstormen voordat je gaat normaliseren.
Ik weer zat even te kijken naar mijn model dus daarstraks ben vandaag weer beetje verder gegaan. Maar volgens mij heb ik een fout gemaakt.
Nu is het zo dat tabel 'links', 'blogs', 'downloads' gelinkt zijn aan de tabel 'TagsKey'. Waarbij de 'key_id' de primary key is dus van de drie databases (en dus ook niet uniek zal zijn). Onderscheid tussen beide 3 maak ik met tag_type. Maar nu kan ik eigenlijk dus toch niet 'on delete cascade' toepassen met Innodb? Zodat wanneer je dus een blog verwijdere ook meteen alle links tussen die blog en de tags werden verwijderd.
Nu wil ik eigenlijk wel graag cascade toepassen maar dient aan die cascade dus een voorwaarde te gelden namelijk dat bv wanneer ik een blog verwijder dat hij alle key_id's verwijderd die gelijk zijn aan blog_id en tevens moet dan gelden dat tag_type gelijk is aan blog bijvoorbeeld.
Waar tags aan gekoppeld zijn is zo wat handiger op te slaan allemaal in één tabel, maar je moet dan wel ergens hardcoded een lijstje hebben met tag_type's.
Daar mee kom je dan toch in de problemen.
Je kunt natuurlijk voor elk type (resource) een eigen tabel met tags maken. Het nadeel daarvan is dat als je bijvoorbeeld het aantal keer dat een tag gebruikt is bij alle types samen wilt ophalen, dat je dan een lastigere query krijgt met union's.
Bovendien moet je dan in je script al weten welke resources er zijn. Aan de ene kant hoeft dit niet zo'n probleem te zijn omdat het aantal resources waarmee je in je applicatie werkt waarschijnlijk niet echt dynamisch is. Maar een echt mooie oplossing blijft het ook niet.
Dan kun je bij elke delete vanzelf ook de bijbehorende tags verwijderen. Probleem daarvan is dat je voor elk resource zo'n trigger aan moet maken.
Een derde manier is om dan maar een extra query uit te voeren om gelijk de koppeling naar de gebruikte tags te verwijderen. Eigenlijk doe je dan hetzelfde als met zo'n trigger, maar dan wat minder ingewikkeld.
Ik heb zelf nog geen ervaring met triggers, maar ik heb wel gelezen dat je super (?) rechten oid nodig hebt om ze te kunnen gebruiken. Dat is dan misschien wat minder handig als je je applicatie ergens wilt hosten waar je beperkte rechten hebt.
<?php
/**
* SN_Zend_View_Helper_HasPrivilege
*
* This helper is to determine if the user has the correct privileges to execute an action
*
*/
class SN_Zend_View_Helper_HasPrivilege {
public function HasPrivilege($Fresource_string, $Fprivilege_string = null) {
$Lacl_obj = Zend_Registry::get('acl');
// get role
$Lrole_string = Zend_Auth::getInstance()->getIdentity()->role;
if (Zend_Registry::get('config')->config->acltype == 'dynamic' && $Lrole_string != 'support') {
$Lrole_string = 'user';
}
if ($Lacl_obj->has($Fresource_string)) {
return $Lacl_obj->isAllowed($Lrole_string, $Fresource_string, $Fprivilege_string);
} else {
$Ldata_array['role'] = $Lrole_string;
$Ldata_array['resource'] = $Fresource_string;
$Ldata_array['privilege'] = $Fprivilege_string;
$Ldata_array['base_error'] = true;
Application::renderError('ACL_ERROR', $Ldata_array);
}
}
}
?>
<?php
/**
* SN_Zend_View_Helper_HasPrivilege
*
* This helper is to determine if the user has the correct privileges to execute an action
Deze heb ik geschreven om eenvoudig iets te verbergen of te tonen in de views. simpel $user->hasPrivilege(resource, privilege);
Ik werk met Userrights op zowel group niveau als single user niveau
Een user kan ook tot een bepaalde groep horen en die groep kan gezamelijke rechten hebben.
Harstikke bedankt voor jullie commentaar beide. Zal zo even naar kijken JBke ben net terug van werk.
Maar @Boukefalos ja dan denk ik dat ik het gewoon makkelijk hou en gewoon dan maar een tweede query uitvoer ;) maar ik ga zeker ook even testen op triggers en misschien gebruiken als eventueel alternatief.