2010-07-19 6 views
2

Je construis actuellement une petite application web pour publier des histoires en utilisant PHP et MySQL. Chaque histoire peut être soit un article (avec beaucoup de champs et de données), juste un lien hypertexte/URL, juste une image, ou un fichier téléchargeable avec certains attributs (encore une fois avec beaucoup de champs).tables de concat avec contenu différent

Mon problème est lié à la recherche de la configuration de base de données optimale pour le système. J'ai réfléchi à 3 solutions différentes qui peuvent ou ne peuvent pas fonctionner (les champs ne sont que des exemples, ne pas savoir si les données doivent être stockées dans la base de données ou non):

1) Faire une table pour chaque tapez et juste les UNION. Par exemple:

articles
id | date | title | author | preview | last_edited | category | content

hyperliens
id | date | title | author | url

images
id | date | title | author | thumbnail | fullimg

fichiers
id | date | title | author | filetype | filename | filecontent

Est-il possible de créer une instruction SQL qui va les concaténer de manière à ce que chaque champ soit ajouté aux lignes des tables individuelles et que la ligne individuelle soit "taguée" avec son type en fonction de quelle table? Ou dois-je me contenter des champs communs (le champ 3-4 sera identique pour chaque table) et des recherches individuelles pour chaque rangée?

2) Création d'une sorte de table d'index référençant la bonne table et la bonne rangée en fonction du type?

index
id | type | title | date | referenceid -> soit des articles, des hyperliens, des images ou des fichiers en fonction du champ "type". Est-ce possible d'une manière ou d'une autre lorsque vous utilisez des clés étrangères? Je soupçonne non, mais pas vraiment sûr de ce que vous pouvez et ne pouvez pas faire dans MySQL.

3) Avoir TOUS les champs pour TOUS les types dans une seule et même table et juste rendre le champ spécifique nullable (je n'aime pas vraiment cette solution car elle semble désordonnée).

Des idées?

Je pense que je ne peux pas être la première personne à avoir rencontré le problème des références à différents types/champs d'entités en fonction d'un type de type.

Les idées sont très appréciées.

Répondre

3

Si vous nommez des champs, vous pouvez alors facilement créer une union et ajouter les constantes que vous voulez. Je le fais tout le temps:

Select id, 'articles' as tablename, title, author, 
    preview, last_edited, category, '' as url 
from articles 
UNION 
Select id, 'hyperlinks' as tablename, title, author, 
    '' as preview, '' as last_edited, '' as category, url 
From hyperlinks 
... 
+0

Quelle serait la pénalité de performance de la résoudre de cette façon? Je suis très intéressé à découvrir les différents avantages et inconvénients des solutions possibles. – agnsaft

+0

UNION est intrinsèquement lent. Pour SQL Server, UNION ALL est beaucoup plus rapide - pas sûr de mySQL. Mais comme tout le reste avec des bases de données, la performance dépend de trop de facteurs à isoler. Sauf si vous avez affaire à des données, je ne m'attendrais pas à ce que cette requête soit le point d'étranglement. – Bill

1

Vous avez si peu de champs, il suffit de les mettre tous dans un tableau et d'ajouter un champ de type. Aucun sens compliquant les choses.

2

Je suggère d'ajouter une table stories pour être la table centrale. Cela permet une grande flexibilité dans la conception du système et centralise les données essentielles à une histoire.

Quelque chose le long de ces lignes:

stories 
    id 
    date 
    title 
    author 
    article_id 
    hyperlink_id 
    picture_id 
    file_id 

articles 
    id 
    preview 
    last_edited 
    category 
    content 

hyperlinks 
    id 
    url 

pictures 
    id 
    thumb 
    full 

files 
    id 
    filetype 
    filename 
    filecontent 
+0

Cela n'aura-t-il pas quelques problèmes avec des clés étrangères et des choses comme ça si par exemple article_id n'est pas pertinent pour cette entrée particulière? – agnsaft

+0

FKs peuvent être nul – Donnie

1

j'ajouter une colonne « type » à chaque table qui indique quelle table il est venu, puis faire un équijointure suivi d'un groupe:

SELECT * 
FROM articles a INNER JOIN hyperlinks h 
    ON a.id =h.id AND a.date=h.date AND a.title=h.title AND a.author=h.author 
    JOIN pictures p ON h.id=p.id AND h.date=p.date AND h.title=p.title AND h.author=p.author JOIN files f 
    ON p.id=f.id AND p.date=f.date AND p.title=f.title AND p.author=f.author 
ORDER BY type; 

C'est une requête laide mais elle devrait faire ce que vous voulez ...

+0

Quelle serait la pénalité de performance de la résoudre de cette façon? – agnsaft

Questions connexes