Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm wondering about a potential problem I might get. My problem is let's say I have 2 tables one called speakers and clients. In the client table the client has the speaker IDs of 1,5,8(SAVED in a STRING field) - so I'm using explode() to get the values.
So now I have to call the speaker table 3 times to get the values of each speaker. This introduces the problem that it will get very expensive if there is alot of users online wouldn't it?
Is there an alternative to calling a table from an array of items or something?
I'm not too clued up about all the php approaches to this so any help will be appreciated!
I agree with #RiggsFolly that it may not be the best way to store the data, you could do something like this:
SELECT (whatever fields you want or speakers.* for all) FROM speakers JOIN clients ON clients.id=(clients.id) WHERE speakers.id IN (clients.field_with_speakers_list_string);
I believe that will get you going. It should return what you want. You would just need to replace (clients.id) with the client ID that you already have in your script and change speakers.id to whatever the ID field in your speakers table is called, and change field_with_speakers_list_string to whatever the field in your clients table with the string of speakers is called, and of course change the part of the SELECT to the fields you want to limit it by.
Based on the description of your database, each Client can have multiple Speakers. This is a one-to-many (1-N) relationship, and is typically expressed in two tables. One is a main table, "clients", which stores information about the client, but nothing about the speakers. A subordinate table, "speakers", stores information about each speaker AND the ID of the Client it is associated with.
For example, Speaker 1, Speaker 5, and Speaker 8 all have the same Client ID in the speakers table. The client_id field in the speakers table is called a foreign key.
Now you can get all the speaker information for Client 1 in one query:
select * from clients, speakers where clients.clientid=speakers.clientid and clients.clientid=1
Your current two-table design is flawed because you have the speakeridS column in the clients table. The foreign key column that expresses the ONE in a 1-N relationship should always be in the "many" table, i.e. "speakers".
Since your current speakers table doesn't have client_id information, you'll have to write a data transformer to migrate the string, comma-delimited speakers field in the clients table, to a numeric foreign key field "clientid" in the speakers table. This is a one-time transformation so you can do it in a PHP script:
$query="select * from clients";
$rs=mysql_query($query,$db);
while ($myrow=mysql_fetch_array($rs)){
$clientid=$myrow['clientid'];
$speakerids=explode(',',$myrow['speakers']);
foreach ($speakerids as $speakerid){
if (!is_numeric($speakerid)) continue;
$query="update speakers set clientid=$clientid where speakerid=$speakerid";
mysql_query($query,$db);
}
}
Your application displays the speakers in a checklist. The interface, however, doesn't have to dictate your storage structure. Write a loop and store the client ID in each speaker record.
IF the same speaker works with multiple clients, then you'll need a many-to-many (N-N) table. This is done via a bridging table. In this case, neither clients or speakers table need to know about each other. Create another table called "clientspeakers" which includes at least two foreign keys: clientid and speakerid.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm designing mysql database for a php app, which has two sections: adding advertisement for properties like house shops.. , and searching for them.
I have tables for users, addresses, ads...
The problem is properties table. I don't know if I should split that up into multiple table or should I have one big table? Columns are too many. I have up to 100 fields, like:
Property type: house, shop, fields... Each property type has some fields like bedrooms number for house, and other fields like air conditioning system, facilities, equipments..
What should I do? Should I divide this table into smaller tables?
I'd recommend to use a bridge table. You can see on this Link what the bridge tables are.
Generally, you have 2 choises which are both schema-design:
Using just one table (named property) and add bulk data to it. In this case, fields are your features (like air_conditioning, bedroom numbers and so on). By defining these field as boolean and denoting 1 for "The property has this feature" and 0 for "The property has NOT this feature", You can do what you want.
Using a simple bridge table which is a table that connects the property table to the features which you should define for property items.
Actually the second approach is an applicable approach in database design. Because it is scalable i.e. You can add every new feature every time!
Hope this explanation would help you!
I'd suggest a properties table, a features table, and a property_features table.
Your properties table would have the main information - address, listing owner, etc.
Your features table would be a table in which each row is a possible feature - air_conditioning, rooms, bathrooms, gold_plated_toilets, etc.
Your property_features table would be a list of property_id, feature_id, and an optional value field (which could be true/false values for air_conditioning, or in something like rooms it might be a numeric count).
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I am looking to implement a new database and store students exam data and marks in the database. There are an arbitrary number of students and each student has an arbitrary number of modules with corresponding marks. I need the database to be created so that I am able to query the database and return the students name followed by each of their modules and corresponding marks and then to move onto the next student. This is because I want to display it in PHP with a list of students names in bold and then a table of their modules and their marks.
I initially considered to organise the table like this:
| StudentName | Module | Result |
With a new entry for each module that the student takes and just store multiple students but then I do not know how I would then query the database and retrieve each StudentName individually and then be able to loop through their corresponding modules and results to store it in an HTML table.
Any ideas would be appreciated
Give each table an id field that auto increments
Where you need to link results to modules, for example, you'd add a
moduleID field to the result table to tie the result to the module.
You'd then do queries with joins to bring in both sets of data.
To tie students to modules, you'd need another table that has a
studentID field and a ModuleID field. You'd then query this table
and join on StudentName and Module to get the respective data for
each.
First, you need several tables. One table cannot do it. Create a table for each type of objects. In this case, you need a table for students and one for modules.
Both tables need an id column to identify the rows. Create a primary key on them.
Students table: Id, StudentName
Module table: Id, ModuleName
There is a many to many relationship between students and modules (each student can have more than one module and each module can be chosen by many students). A many to many relationship requires a separate table.
You were not clear if there is one grade per student and module. If there is only one grade, the best solution is to include the grade in this relationship table.
Grade table: Id, StudentId, ModuleId, Grade
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to decide the best possible way to structure my user table. Users can have access to multiple "brands" and each brand will have multiple tables. That is, if user X wants to see data for brand Y, the database contains the information to say which tables I need to make calls to.
For example, user X can access Brand1 and Brand2. Brand1 has its data in table1, table2, and table3. Brand2 has its data in table4, table5, table6. User selects Brand2 and the application makes a call to find out that table4, table5, table6 should be used until user selects a different brand.
What's the best way to structure this knowing that a single brand might have multiple users that can access the data?
Do I need more than just a user table and, if so, what else and how would that connect to the user table?
Thanks.
Like Mark Baker pointed, you can have one user table, one brand table and one user_brand table.
user table - stores user_id (and other user data)
brand table - stores brand_id (and other brand data)
You've already defined relationships between users and brands. It's M:N (many to many), which means that:
one user can have access to multiple brands.
one brand can be accessed by many users.
Table user_brand solves the access problem.
user_brand table - stores user_id and brand_id (and optional data which better describes this relationship).
Here is an example about sql syntax (enforcing foreign key constraints).
You can use GRANT query so the user can access just 2 tables in a database, then in the application, you can code it just to select 1 table, until the user changes the brand. The brand itself is the table, isn't it?
In PHP code, the code and query should be like this:
<?php
$db = new mysqli('hostname', 'db_username', 'db_password', 'db_name');
$brand = $_SESSION['brandName']; // use this if you use sessions to cache the data
$db->query("SELECT * from `$brand`");
I have a MySQL database set up with a list of all my movies, which I imported from a MS Access database. One field contains the possible values for the genre of the movie, movies can have more than one genre, so I need a data type which supports this feature. In access I could link one table 'genre' to the field 'genre' in my table 'movies', so I could choose none, one ore multiple genres per movie. When I switched to MySQL I used the SET data type to define all the possible values. So far everything is running perfectly.
I am now trying to set up a table in html/php to show the mysql table. I want the table to be able to sort on: title, genre, quality, rating, etc. But for the sorting on genre, I would need the possible values from the set data type. I don't know if it is possible to get the values with some php command/code, but after I lurked around on the web for a while, I didn't see many applications where they use the SET data type for obvious negative reasons.
So I started looking into the Foreign Key possibility. The problem I have here is that -for as far as I know- the key can only contain one possible value, which puts me right back at the start of my problem. I do like the idea of a foreign key, because it would make it way easier for me to add a new genre to the list.
Is there a possibility I am overlooking? Is it possible to either get the values from the SET type to php or to use a foreign key with multiple possibilities for one record?
I know I can also put every genre in my php script manually, but I'd like to have it all on one place. So that if I add a movie with a genre I haven't defined yet, I can just update it at one place and everything else adapts to it.
Dagon is absolutely right here - you have an issue with the structure of the tables in your back end. You are wanting to model a many to many relationship when at the moment with your current back end the best you can do is a one to many relationship.
To review:
You have individual films that can have many genres
And you have individual genres that are related to many films
Relational databases actually don't model many to many relationships with one relationship they use recursion of the one to many relationship and create two joins.
To model a many to many relationship you need three tables
A film table (which I think you already have)
A genre table (which I think you already have)
A junction table which as Dagon suggests will consist of two fields film id and genre id.
You then set up two separate one to many relationships. One from the film table to the junction table and one from the genre table to the junction table.
Now if you want to know all the genres a film is in you simply filter the junction table on the relevant film id and if you want to know all the films with a certain genre you filter the junction table on the genre id.
Set up lookups to relate your genre ids to textual descriptions and bang you are free to change the textual description as much as you want and the great thing if you've done it right it will upgrade every single value in your forms.
This is an absolute fundamental concept of the algebra of sets behind the design of SQL and relational database design.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm new to PHP and MySQL. For my project I want to make a site for lyrics. How to design the database and the relationships?
Here is what I have so far:
Artist
Artist_id
Artist_name
Artist_bio
Artist_thumb
Albums
Album_id
Artist_id
Genre_id
Album_title
Release_year
Genre
genre_id
genre_name
Tracks
track_id
track_title
album_id
Please let me know if I'm wrong.
Be consistent with whether your
table names are singular or plural. My preference is singular, because then when you're doing multi-table queries, you can refer to a column simply as "track.id", rather than "tracks.id".
Ensure all your table and field
names are spelled correctly (i.e.
"genre"); this is something that's a
pain to change later.
Finally, I wouldn't advise prefixing the column names with their parent table's name. It's just redundant.
artist
id
name
bio
thumb
album
id
artist_id
genre_id
title
release_year
genre
id
name
track
id
title
album_id
I strongly recommend WWWSQLDesigner to design your database. Guideline that brianreavis had mentioned are really worthy of listening. Always use correct spelling, use consistent grammar, capitalization and underlining (_). Also you may consider adding multiple genres using a relationship table.
album_genre ( id int, album int, genre int )
For album or artist pictures, I recommend you to save them to a folder with their related id's. Observe,
id = 14
artist = 42
title = Mask And Mirror
year = 1994
thumbnail: /thumbnails/album-14.jpg
Your design looks pretty good. Some additional tables that you may want to add:
Playlist
PlaylistTrack
PlayedTrack
You could add additional fields to the Track table. For example:
trackSortOrder
trackYear
trackGenre
trackLength
userRating
bitRate
author
copyright
numberOfPlays
lastPlayedDate
dateAdded
Important questions you should be asking yourself while designing
What is my requirement!?! In your case, what all information should my lyrics website have? Should it tell me who actually wrote the song? When was it written? Who all have sung that song etc etc. So first thing is you have to define the scope! Your Entities and database design will depend on that!
What are my entities?
what are the relationships between my main entities?
Your design might be pretty descent and might work perfectly for your requirement but depending on how much of complexity you are willing to handle (requirement scope!), you might have to take care of things like:
Artist and Album actually have many to many relationship. Many artists might work on same album and of course a single artist will have multiple albums. Your current design will cope up with this but do you want genreId, title, release_year being duplicated when multiple artists work together for an album? There is a trade off involved here between creating 1 more table and storing duplicate values. Your current design might be perfect for what you are doing, but just wanted to make sure that you have given it a thought
In real world, multiple artists collaborate to write a song. Mostly songs are written by someone else and sung by someone else. You need to define what Artist means to you. Is it the person who sung the song? Is it someone who wrote the song? Are both artists? If I search for the writer of the song who has not sung a single song, should it return results?
I dont see a table where you are storing lyrics! But I guess you already know that :)
I can see a few more things which might cause you problems later on, but as I said, I don't know what is the scope of your requirement! :)
You're conflating multiple different types of objects in a few places -- for instance, it looks like you're trying to create a single rating table which applies to albums, artists, and tracks. Consider carefully whether it may be easier to have three separate tables for the three different types of ratings.
Same thing goes for comment. Additionally, on that table, your current structure (having a single comment_id on an album, artist, or track) would appear to limit each type of object to having a single comment, which doesn't make sense.
For genre, type, and thumb, consider inlining those tables into the parent object. Would it ever make sense to have a single thumb row which is shared between multiple artists, for instance, or would it be easier to just have each artist have a thumb path stored directly in it?
Finally, for all of the relationships you've drawn out, you need to define the cardinality of the relationship. For each one, define which table is referring to the other, and "how many" rows in one table can exist for each row in the other one. For instance, the relationship between album and track is a one-to-many relationship, as each album contains multiple tracks, but each track belongs to one album. Use a notation such as "crow's foot notation" to denote this information.
How about having a separate table for album and a common table which defines the relationship between all the other tables?