Worried about too many fields in table - php

i am currently planning out my next project which is a text based mmorpg game. I am currently trying to design certain parts of the database and have hit a bit of a problem that i have never had before. One part of the game allows the player to buy a car and add addons to it. I was going to have a different table altogether to manage the addons for the car, but a user could have up to 100 addons for a single car, which would require over 100 fields, of course i am not happy with this many fields in one table as it could become difficult to manage, is there any other way to split them up into multiple table?
Thanks

Why does each addon have to be a separate column? Couldn't you have a many-to-many join table that would link car to addon?
Car
ID | Owner
1 | Jacob
2 | Mary
Addon
ID | Name | Price
1 | Flame decal | $10
2 | CD Changer | $150
Car_Addon
Car_ID | Addon_Id
1 | 1
1 | 2
2 | 2
This indicates that Jacob's car has a flame decal and a cd changer, while Mary's car only has a cd changer.
Advantages of this approach:
You can use foreign key constraints to ensure that no invalid records can be created
It's easy to query in either direction -- which addons does this car have or which cars have a given addon
The meaning of the relation is clear -- you're not relying on decoding serialized data within a single field
You can store data about the association between car and addon -- the car_addon table can have a column for when the addon was added to that car, how it was paid for, whether it was part of a discount package, etc.

You have a many-to-many relationship between cars and addons. You need an intermediary junction table to resolve that relationship.

No.
Split them into multiple tables. If you have 100+ fields in a table, 99.9% of the time you haven't normalized your design enough. A sure sign of a badly structured database is a lot of sparsely populated fields.
Why are you hesitant to split it?

You should have a table for Cars (ID, Name) for example, one table for ADDON (ID, Name) too and another table to link these talbes called CAR_ADDON (idCar, idADDON).
That would be the best approach

Related

Which is the best in performance having 1 to many relationships on tables

I have a table company in which I am saving company information and I want to save N number of company locations for that particular company (country_id, city_id). 1 company has Multiple locations. I have to save country and city in database in such a way that if user wants to view company filter by Country or filter by city, it will search very fast (Indexing applied).
Which option will give me better performance in terms of fast search, Normalization?
Option 1:
Should I maintain country id and city id in JSON and save it in Company table?
No need of new table. every time I will add or update JSON based on users selections.
for e.g.
[{"country1" : {city1, city2, city3}},
{"country3" : {city5, city1, city3}}]
Then I can (LIKE) query on this field -> decode json -> return result
option 2:
Should I create new table and save country's and city's PK along with
company_id FK.
company_id (FK) | country id | city id
1 | 25 | 12
1 | 25 | 16
1 | 25 | 19
1 | 30 | 1
1 | 30 | 69
1 | 30 | 14
then just query and return result
Normalize if you're using traditional SQL.
MongoDB and other similar systems for storing hierarchical data (MarkLogic, etc) have ways of making the search of JSON docs fast.
But searching and updating denormalized data is an unreliable pain in the neck in SQL. With the volume you have, it will be very slow.
Option #2, meaning creating a separate table for company location is the best option. Use the combination of all 3 columns to create the primary key as a clustered index.
Never, under any circumstances, will a delimited value column be more efficient then lookup tables in a relational database. the cost of using Like or parsing the data (not to mention if you are using the like operator to get more results then needed and then parse the data in code) is always higher then the cost of querying a well indexed normalized tables with a simple inner join.

Associate two MySQL rows

This is a bit confusing. I cant find how to word it for google and I just cant wrap my head around the logic to do this.
I have "contacts" and "sites" tables that I am storing data for in a database. We need to have a page showing the contacts information and what "sites" they are associated with AND have a page for information about a "site" and show what contacts are associated with it.
Right now I have a field for "contacts" that has comma separated ids of each site that its associated with and a field for "sites" that also has comma separated ids of each contact associated with that site.
When I create a new site with an associated contact. how should the logic go that will update the "associated sites" field on the contacts row in MySQL while also updating its own "associated contacts" field?
I think, you are speaking about many-to-many relationships.
I assume you have a table design like this:
tbl_contacts tbl_sites
id | full_name id | label
1 | John Doe 1 | my website
3 | Maria Doe 2 | super website
You need a table to "link" the tables. this is a many-to-many-table:
tbl_contacts2sites
id | contact_id | site_id
1 | 1 | 2
5 | 1 | 1
3 | 3 | 2
So, John Doe is assigned to both sites, but Maria only to the "super site".
This is the common way to design your relationships. You should avoid any comma seperated lists for this kind of relationships.
The best solution would be when you create a third table (contacts2sites) in this table you have three columns called: id, siteid, contactid.
In this table you can add every connection between sites and contacts. To query the data out of it you can use the mysql query with joins over all tables.
little example:
solution with joins

Customer reviews and calendar entries, etc in a database

How would things like customer reviews be stored in a database? I cant imagine there would be rows for each item and columns for each review as one product may have 2 reviews and another may have 100+ - id presume they were stored in a separate file for reviews but then surely not one file per item! I dont know enough about storing data to be able to figure this one out by myself!
A similar situation is something like an online calendar - there is all the information about each appointment (time, duration, location, etc) and there can be many of these on each day, every day, for all users! A logical way would be to have a table for each user with all their appointments in, but at the same time that seems illogical because if you have 1000+ users, thats alot of tables!
Basically Id like to know what the common/best practice way is of storing this 'big dynamic data'.
Customer reviews can easily be stored by using two tables in one-to-many relationship.
Suppose you have a table containing products/articles/whatever worth reviewing. Each of them has an unique ID and other attributes.
Table "products"
+-------------------------------------+
| id | name | attribute1 | attribute2 |
+-------------------------------------+
Then you make another table, with its name indicating what it's about. It should contain at least an unique ID and a column for the IDs from the other table. Let's say it will also have an email of the user who submitted the review and (obviously) the review text itself:
Table "products_reviews"
+--------------------------------------------+
| id | product_id | user_email | review_text |
+--------------------------------------------+
So far, so good. Let's assume you're selling apples.
Table "products"
+-------------------------------+
| 1 | 'Apple' | 'green' | '30$' |
+-------------------------------+
Then, two customers come, each one buys one apple worth 30$ and likes it, so they both leave a review.
Table "products_reviews"
+-------------------------------------------------------------------------------+
| 1 | 2 | alice#mail.com | 'I really like these green apples, they are awesome' |
| 2 | 2 | bob#mail.com | 'These apples rock!' |
+-------------------------------------------------------------------------------+
So now all you have to do is to fetch all the reviews for your apples and be happy about how much your customers like them:
SELECT *
FROM products_reviews
INNER JOIN products ON products_reviews.product_id = products.id
WHERE products.name = 'Apple';
You can now display them under the shopping page for apples (just don't mention they cost 30$).
The same principle applies for things like an online calendar. You have one table with users, and many tables with other stuff - appointments, meetings, etc. which relate to that user.
Keep in mind, however, that things like meetings are better displayed in a many-to-many table, since they are shared by many people (usually). Here's a link that visualizes it very good, and here's a question here on SO with sample code for PHP. Go ahead and test it for yourself.
Cheers :)

CakePHP Normalization

I am debating over the amount of normalization to use in my tables.
For example, if I have a database table called players with columns such as name, hometown, etc...
Other columns are options bats (right, left, or switch), or status (active, injured) that with be displayed as radio buttons or drop downs.
Currently, our database stores these options in their own tables bats and statuses and we reference the related table with the fields bat_idand status_id.
If the bats and statuses tables are simply storing a list of names and ids and will always have less than 10 values, should I flatten the database and simply store the values directly in the players table?
When creating radio inputs for those fields I might have to execute a group by query on a large table. Would it make sense to store the possible values globally as an array in app/config/bootstrap.php or by using the configure class?
For my opinion you can really seldom overuse normalization. I'd avoid globals as much as I can.
If your bats and statuses tables will hold "only" configuration or status key data you might put all of them together in a single table, accessible by namespace.
E.g.:
id | namespace | value
---------------------------
1 | bats | left
2 | bats | right
3 | bats | swing
4 | status | active
5 | status | injured
... etc, you get it. Simply have an index on the namespace to help the database - unless there are really only a few lines in there where a decent DB would ignore the index anyway.

OO design issue (using Symfony2)

I'm developing a sports court booking system and I need to generate a "booking table" that shows the columns in the table header as courts and the rows as time slots for bookings.
E.g.,
___________________________________
| | | |
| Court 1 | Court 2 | Court 3 |
|___________|___________|___________|
| | | |
| 10.00 am | 10.00 am | 10.00 am |
|___________|___________|___________|
| | | |
| 11.00 am | 11.00 am | 11.00 am |
|___________|___________|___________|
Requirements:
A club can have any number of courts
A club can have any time increment for bookings (e.g., 1 hour as shown above, 30 minutes, 40 minutes, etc)
Each cell in the table represents a "booking"
I want to make sure I do this right from the start so I have a few questions:
What entities would you create to achieve this
How would you go about generating this booking table
How would you link a cell in the above table to a booking
Thanks in advance.
Well, I think this is kind of standard?
First, you need a club entity. Each club can have n courts:
Club 1:n Court
Then there is a booking table, which is 1:n to a court:
Court 1:n Booking
I don't know if your second requirement means that one club has one time increment (in which case this is one variable on the club entity) or if it can has many (than there would be a TimeIncrement entity.
Generating the table can be a bit tricky. Thinking about it for a few minutes I got like 5-6 solutions which might work. You could use special objects which you can ask for the booking for a specific court and time and which search a Collection. Our you could build up an array where you have one key for every time and if there is no booking it's null. Have one array for each court, than do 2 nested for loops and read every value from the arrays. You could build up queries which rearrange the data so you can use them directly. Or maybe you can ask the court object itself for the booking on a specific date and time.
But I guess that is what the developer is for... Find out what works best for the given requirements and implement it.
What entities would you create to achieve this
Off the top of my head it looks like you'll need 3: Club, Court, Booking
How would you go about generating this booking table
The table should probably consist of id, court_id, start_time, end_time
How would you link a cell in the above table to a booking
As mentioned above, start/end times are columns in the bookings table.
I would just query the data from the database and turn it into json and pass it into the website. The frontend then can build the table with javascript.
For that I would create a custom entity BookingTable that returns data on request directly as an array which then can be easily turned into json with json_encode.
You can then concentrate on the more detailed pages that show the single booking for which you will automatically create the entities you need (if you didn't already to formulate the DQL for the custom entity for the table).

Categories