database relation tables - mysql

Well im working on an online game project where every player will get to have a house, the project was going great until u had to organize houses thinking that i will have a limit of 10.000 players on the server.
so here are some facts:
each player may have up to 10 houses (min 1).
that means i need 100.000 possible houses so that no matter how full the server gets, there will always be 10 possible houses for each player.
there will be 20 cities, each city will have 200 neighborhoods, and each neighborhood will have 25 houses
so thats when the problem shows up, how would the database work?
whenever i want to see any of the 100.000 houses, it will belong to a neighborhood on a city, and i need to be able to play with that, like if i want to see house #5 of the neighborhood #123 city#8, then i should be able to get the data.
i was thinking about having one table with all 100.000 houses, and having values on that table to tell what neighborhood it is on what city, but it feels like there must be a better way. (maybe using multiple tables? i dont know)
so any help would be appreciated.
thank you for your time.

It's hard to answer, because your complete requirements aren't known.
But I'd recommend that you normalize the database - 3rd normal form at minimum. If you don't know what that is, I'd recommend learning about it ASAP.
My best guess is as follows:
PLAYER is one-to-many with HOUSE. If more than one PLAYER owns the same HOUSE, then it's many-to-many.
CITY is one to many with NEIGHBORHOOD
NEIGHBORHOOD is one-to-many with HOUSE
You'll do JOINS to associate a PLAYER with cities, neighborhoods, and houses. You should have surrogate primary keys on all tables and appropriate foreign keys. Add UNIQUE indexes on all other candidate key combinations.
Run EXPLAIN PLAN on all your queries to make sure that they don't require TABLE SCAN and perform adequately.
10,000 players isn't a big number for a database. You won't have any problem.
Here's what your query to select all the houses in a neighborhood might look like:
SELECT *
FROM HOUSE H
INNER JOIN NEIGHBORHOOD N
ON H.HOUSE_ID = N.HOUSE_ID
INNER JOIN CITY C
ON N.NEIGHBORHOOD_ID = C.NEIGHBORHOOD_ID
WHERE C.CITY_ID = 8
AND N.NEIGHBORHOOD_ID = 123
ORDER BY H.HOUSE_ID

Related

SQL, Laravel: When to create a relationship?

I'm exploring the fields of SQL and relational databases since I'm relatively new to database design and I was wondering about how table/object relationships work. By relationships I mean referencing an id on another table, which is heavily used in frameworks like Laravel with it's ORM Eloquent. In the Documents it's stated how to create relationships, but not WHY and WHEN? What are the benefits or the drawbacks of not doing it?
So my question; When and why do we need to create relationships between tables?
Example:
I was practicing on a Laravel Application for our local indoor Football/Soccer Club which uses multiple tables (and what made me confused about the concept). The tables/resources of my app are:
Competitions
Teams
Matches
Locations
To clear up: There are 7 competitions of 12 teams (so total 84 teams total) who play matches at 3 indoor courts. The matches of every competition are not tied to 1 court, so competition 2B has matches at court 1 and 2 par example.
The target of my app is to show the program/schedule, fixtures and rankings of the different competitions. I want to use relationships so I can retrieve all matches played at court 1 or all matches of competition 2A.
I presumed the relations to be like this:
1. Competitions -> hasMany Teams, | Teams -> belongTo Competition
2. Competitions -> hasMany Matches | Matches -> belongTo Competition
3. Location -> hasMany Matches | Matches -> belongTo Location
4. Matches -> hasMany Teams | Teams -> HaveMany Teams
I created the migrations and the models but I bump into error after error. For example every match has two teams, how to specify this relation? And matches, they belong to a competition and as well to a Location so I can query both locations with all their matches and competitions with all their matches.
Is this all even possible or does evert table can only have one parent/child relation?
Maybe someone has some good resources on this matter for beginner to novice for me to learn and grasp the basics of this matter.
Thanks in advance!
i'm going to try to give you a quick answer.
Basically you create relationships between your models because they are part of their definitions.
WHY ? Because it helps in many cases.
If we take your first relationShip :
1. Competitions -> hasMany Teams, | Teams -> belongTo Competition
Defining that relationship will ease the following operations :
Define the teams which are part of a competition.
$competition->teams()->save($newTeam);
Retrieve the teams which are part of a competition.
$teams = $competition->teams();
Retrieve the competitions which are played by a certain team.
$competitions = $team->competitions();
as those kinds of operations are very common Eloquent ORM allows you to use his simple and efficient syntax instead of writing sometimes complex SQL requests.
WHEN ? Anytime those kinds of relations exists between your models, declare them, always.

Database design issue, should i prevent crossing relations?

I have a database that seems to be challenging to my knowledge on database design.
I will try to explain and then I will ask the question.
I have a list of companies that have interact with the system and those companies can operate within my country and only my country, all the companies are dedicated to fishing activities. Those companies can have product providers or just fish by themselves. Those providers can operate in any country. The products bought from providers (most of them are frozen fish) can also come from any country and it is not necessarily the provider's country.
Of course I have a country table with the default value set to my country, that table is also referenced by providers and products.
Well, with this design, there is no way to avoid relationships crossing. But my real question are,
is it a good practice to allow this to happen?
If not, how should i redesign it to fix it?
If yes, why everyone tells me to prevent this kind of relations?
Thanks!
Your database design should be OK. Something that need to defined with different country should have to be. There is no something "crossing" logically with it.
The one thing you should avoid in database design is Circular Relation which is A need B, B need C and C need A.
Well, let's analyse the situation:
Those companies can operate within my country and only my country
I'm assuming the companies are represented by the user table; technically they wouldn't need a country, but looking ahead you may want to have companies from other countries.
Those providers can operate in any country.
Okay, so provider definitely needs their own country field.
The products bought from providers (most of them are frozen fish) can also come from any country and it is not necessarily the provider's country.
So product also needs their own country field.
Basically, you will want to represent a product from country X, bought from a provider of country Y and delivered by company from country Z. The model you have designed seems to reflect those relationships correctly.

MYSQL Relational Schema Planning

I'm trying to figure out the best way to manage this data storage problem....
I have a table of players, teams, and competitions.
A team may be involved in let's say 3 competitions.
A player belongs to a team, but may only be eligible to play in 2 of the 3 competitions that his or her team plays in. Likewise another player of the same team may be eligible for all 3.
I don't want to add a column to the player table for each competition as I'm then moving away from the relational model. Do I need another table 'competition_eligiblity' - this seems like a lot of work though!
Any suggestions?
Thanks,
Alan.
Yes, you do need a table for competition eligibility.
It really is no more work to put it there. Actually, it will be less work:
Adding a new competition in the future will be a real pain if it involves adding a new column to a table.
If the competition eligibility is stored in columns, performing a query to get information on eligibility becomes a nightmare.
Suppose you wanted to list all the competitions players are eligible for. Here would be your query:
select player, "competition1" from players where competition1_eligible = 1
union all
select player, "competition2" from players where competition2_eligible = 1
union all
select player, "competition3" from players where competition3_eligible = 1
union all
select player, "competition4" from players where competition4_eligible = 1
Sounds like fun, eh? Whereas, if you have an eligibility table, this information will be very simple to get.
Update: storing all the eligibility info in a single value would be even more of a nightmare, because imagine trying to extract that information back out of the string. That is beyond the limits of a sane SQL query.
Creating a new table is really a trivial piece of work, and you only have to do that once. Everything after that will be much easier if you do it that way.

help with making SQL query efficient in MySql

I have 30 tables, each representing a different neighborhood.
Each table holds real estate listing with a "Price", "Number Of Rooms", "Square Feet" etc columns.
The end user would be able to choose as many neighborhoods as he likes with the
option to screen out results such as "At least 5 Rooms", "Below 250k" etc and
sort the results by "Lowest Price", "Time Submitted", you get the point.
Now I'm a programmer not a DBMS guy. I've search the web but feel that trying to build the query one step at a time would be the wrong approach without some guidance on what to avoid.
I would love to hear and learn from the StackOverflow community on best approaches with this one. Please help me sort this up.
EDIT: i'm currently using MyISAM
You should not have 30 tables. Normalize your schema:
NEIGHBORHOOD
ID, Name
PROPERTY
ID, NeighborhoodID, Name, Price,
Rooms, SquareFeet
Then you can join these together:
SELECT n.Name AS Neighborhood, p.Name AS Property, Price, Rooms, SquareFeet
FROM Property AS p
INNER JOIN Neighborhood AS n ON h.NeighborhoodID = p.ID
WHERE p.NeighborhoodID = X
Then you may need indexes on the tables as the data grows.
You should start modifying your database model. Creating 30 tables for storing the same data (real state information) is not adequate. Try to put all the data in a single table adding a column that indicates the neighborhood. This neighborhood could point to another table with the name, description, ... of the neighborhood. Then you can query a single table to search across all neighborhoods and optionally filtrate the neighborhood the user want to search for.
The best way is to change your db model, get rid of 30 tables, and put everything in one table. With your current model, I don't see any other ways but create a huge union (you can put it into a view, and query this view).

How to design this "bus stations" database?

I want to design a database about bus stations. There're about 60 buses in the city, each of them contains these informations:
BusID
BusName
Lists of stations in the way (forward and back)
This database must be efficient in searching, for example, when user want to list buses which are go through A and B stations, it must run quickly.
In my first thought, I want to put stations in a seperate table, includes StationId and Station, and then list of stations will contains those StationIds. I guest it may work, but not sure that it's efficient.
How can I design this database?
Thank you very much.
Have you looked at Database Answers to see if there is a schema that fits your requirements?
I had to solve this problem and I used this :
Line
number
name
Station
name
latitude
longitude
is_terminal
Holiday
date
description
Route
line_id
from_terminal : station_id
to_terminal : station_id
Route schedule
route_id
is_holiday_schedule
starting_at
Route stop
route_id
station_id
elapsed_time_from_start : in minutes
Does it looks good for you ?
Some random thoughts based on travel on London buses In My Youth, because this could be quite complex I think.
You might need entities for the following:
Bus -- the physical entity, with a particular model (ie. particular seating capacity and disabled access, and dimensions etc) and VIN.
Bus stop -- the location at which a bus stops. Usually bus stops come in pairs, one for each side of the road, but sometimes they are on a one-way road.
Route -- a sequence of bus stops and the route between them (multiple possible roads exist). Sometimes buses do not run the entire route, or skip stops (fast service). Is a route just one direction, or is it both? Maybe a route is actually a loop, not a there-and-back.
Service -- a bus following a certain route
Scheduled Run -- an event when a bus on a particular service follows a particular route. It starts at some part of the route, ends at another part, and maybe skips certain stops (see 3).
Actual Run -- a particular bus followed a particular scheduled run. What time did it start, what time did it get to particular stops, how many people got on and off, what kind of ticket did they have?
(This sounds like homework, so I won't give a full answer.)
It seems like you just need a many-to-many relationship between buses and stops using 3 tables. A query with two inner joins will give you the buses that stop at two specific stops.
I'd hack it.
bus_id int
path varchar(max)
If a bus goes through the following stations (in this order):
01
03
09
17
28
Then I'd put in a record where path was set to
'-01-03-09-17-28-'
When someone wants to find a bus to get from station 03 to 28, then my select statement is
select * from buses where path like '%-03-%-28-%'
Not scalable, not elegant, but dead simple and won't churn through tables like mad when trying to find a route. Of course, it only works if there's a single bus that goes through the two stations in question.
what you have thought is good, in some cases it may or may not be efficient. I think that yo u should create tables as table1(BusID, BusName) table 2(Station List, Bus Id). I think this would would help. And try to use joins between these two tables to get the result. One more thing if possible try to normalize the tables that would help you.
I'd go for 3 tables :
bus
stations
bus_stations
"bus" for what the name stands for, "stations" for the station id's and names, and "bus_stations" to connnect those other 2 tables, wich would have bus_id, station_id_from station_id_to
This is probably more complex that you really need, but if, in the furure, you need to know the full trajectory of a bus, and also, from witch station one bus comes when it goes to "B station", will be usefull.
60 buses will not make that much impact in performance though.