I have a table with projects in it and each one has a number to identify the project uniquely.
I want to make a many-to-many table to link projects together and this will be done by the user through a GUI. This table would have columns project_id_1 and project_id_2. I wonder what the most efficient way to query the table would be if there are many projects randomly linked together
I could have something like :
id1
id2
1
2
3
4
5
6
2
6
4
5
In this case all the projects are linked together.
But trying to query this seems impossible without looking through the whole table.
Does anyone have an idea how this could be done better?
Thanks
So in the end I didn't find any MySQL black magic. I just used java and multiple queries.
It would have been nice to find a more elegant solution though. I can't be the only one faced with such a case.
Related
I have a question regarding junction tables and I really hope you can help me out as it is confusing me. I know that junction tables are usually implemented to create two one-to-many relationships instead of one many-to-many, but see the example below:
In a hypothetical situation where a user can have multiple photos (like a portfolio) but there are also groups that can have multiple photos.
The situation would look something like this I believe (please correct me if I'm already wrong here):
Image 1
But isn't it preferable to create a situation using junctions tables like the image below:
Image 2
In this way you prevent the Photo table from getting alot of NULL values, assuming you set the two foreign keys, User_ID and Group_ID, to NOT NULL.
Thank you for your time and I hope someone could guide me with this.
Here is what I have done... I create a relator table that has three columns
leftsideID, relatortype, RightSideID
In your case.. you have two relationship types that connect photos to things.
Users and groups.
So I would have two relatortypes USERPHOTO and GROUPPHOTO.
All the RightSideID's point to photo keys in the photo table.
All leftside ID's either carry the userid or the groupid, based upon the relator type, example could be:
leftsideid relatortpype rightside
========== ============ =========
1 'userphoto' 1
2 'groupphoto' 1
1 'userphoto' 2
This says (in three rows), that user1 has two photos(1,2) and group2 has photo(1)
no nulls. I have used design pattern alot to a high degree of success.
Its basically a generic Junction Table, given your example.
Im working on a project. Its mostly for learning purposes, i find actually trying a complicated project is the best way to learn a language after grasping the basics. Database design is not a strong point, i started reading up on it but its early days and im still learning.
Here is my alpha schema, im really at the point where im just trying to jot down everything i can think of and seeing if any issues jump out.
http://diagrams.seaquail.net/Diagram.aspx?ID=10094#
Some of my concerns i would like feedback on:
Notice for the core attributes like area for example, lets say for simplicity the areas are kitchen,bedroom,garden,bathroom and living room. For another customer that might be homepage,contact page,about_us,splash screen. It could be 2 areas and it could be 100, there isn't a need to limit it.
I created separate tables for the defaults and each is linked to a bug. Later i came to the problem of custom fields, if someone wants for example to mark which theme the bug applies to we dont have that, there is probably a 100 other things so i wanted to stick to a core set of attributes and the custom fields give people flexibility.
However when i got to the custom fields i knew i had an issue, i cant be creating a table for every custom field so i instead used 2 tables. custom fields and custom_field_values. The idea is every field including defaults would be stored in this table and each would be linked to the values table which would just have something like this
custom_fields table
id project_id name
01 1 area(default)
12 2 rooms(custom)
13 4 website(custom)
custom_field_values table
id area project_id sort_number
667 area1 1 1
668 area2 1 2
669 area3 1 3
670 area4 1 4
671 bedroom 2 1
672 bathroom 2 2
673 garden 2 3
674 livingroom 2 4
675 homepage 4 1
676 about_us 4 2
677 contact 4 3
678 splash page 4 4
Does this look like an efficient way to handle dynamic fields like this or is there other alternatives?
The defaults would be hard coded so you can either use them or replace with your own or i could create a another table to allow users to edit the name of the defaults which would be linked to their project. Any feedback is welcome and if there something very obvious with issues in the scheme please feel free to critique.
You have reinvented an old antipattern called Entity-Attribute-Value. The idea of custom fields in a table is really logically incompatible with a relational database. A relation has a fixed number of fields.
But even though it isn't properly relational, we still need to do it sometimes.
There are a few methods to mimic custom fields in SQL, though most of them break rules of normalization. For some examples, see:
Product table, many kinds of product, each product has many parameters on StackOverflow
My presentation Extensible Data Modeling with MySQL
My book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming
I found this as was searching for something similar as the customer can submit custom fields for use later.
i settled for using data type JSON which i appreciate was not available when this question was asked.
I have this example tables:
table ORDERS
client orderno cant1 code1 notes1 cant2 code2 notes2 cant[i] code[i] [...]
--------------------------------------------------------------------------------------
1 1 3 AA01 Test 4 BB01 Testing
2 2 10 XX05 Test
table PRODUCTS
code prod price
---------------------
AA01 Engine 100
BB01 Wheel 50
table CLIENTS
client name address telephone
-----------------------------------------
1 Maxwell 24 1st st 0987654321
2 Hammer 77 main st 1234567890
I need to relate them to get the quantity, name of the product and price for each of the product lines (they are 30 cant[i], code[i] and notes[i]) and the customer's information (name, address, etc)
I found this case, but I don't understand how to apply it to mine: SQL query two tables with relation one-to-many
I hope it's not too complex.
Thanks in advance!
EDIT
Thanks to ElectricLlama I realized the problem here is the table where the order is storaged. According to his answer, the normalization of the database would improve the way I'm able to get the info.
For anyone interested in this solution, I found this great website: http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/
This SO answer clears it ALL! Super clear and understandable!
https://stackoverflow.com/a/1258776/888292
Looking at what's in your link - yes it seems like a lot of nonsense, but it is probably the only way to get what you want.
The problem is that your table is not normalised. Specifically you should not have fields called code1 code2 code3 code4... code30
There are many flaws with this design including what happens when a client has 31 products?
In a normalised database you would have a table with one set of cant, code and notes, and you would have one row per product.
But I guess you are not in a position to normalise it.
So well done for coming up with your own answer, and you now you also have first hand experience of the repercussions of not normalising a database.
What you might want to consider is creating a view that will normalise this for you. It will introduce performance issues but it will give you an introduction to views, and give you an opportunity to see how the solution would look like against a normalised table.
Ditto #ElectricLlama & here are a few links that should help you learn SQL:
W3Schools: SQL Tutorial
SQLServerCentral.com Stairway Series
I think that your table should be look like
Table orders
-------------
orderno
client
code
cant
note
Here make orderno, client and code make a composite primary key of the table
I am creating a database for a publishing company. The company has around 1300 books and around 6-7 offices. Now i have created a table that displays the stock items in all locations. The table should look like following to the user:
Book Name Location1 Location2 Location3 ......
History 20000 3000 4354
Computers 4000 688 344
Maths 3046 300 0
...
I already have a Books table which stores all the details of the books, i also have a office table which has the office information. Now if i create a stock management table which shows the information like above i will end up in a huge table with a lot of repetition if i store my data in the following way:
Column1- Book_ID Column2- Location_ID Column3- Quantity
1 1 20000
1 2 3000
1 3 4354
2 1 4000
2 2 688
...
So, i think this isn't the best way to store data as it would end up with 1300 (Books) X 7 (Locations) = 9100 rows. Is there a better way of storing data. Now i can have 7 additional columns in the Books stable but if i create a new location, i will have to add another column to the Books table.
I would appreciate any advice or if you think that the above method is suitable or not.
Nope, that's the best way to do it.
What you have is a Many-to-Many relationship between Books and Locations. This is, in almost all cases, stored in the database as an "associative" table between the two main entities. In your case, you also have additional information about that association, namely, it's "stock" or "quantity" (or, if you think about it like a Graph, the magnitude of the connection, or edge-weight).
So, it might seem like you have a lot of "duplication", but you don't really. If you were to try to do it any other way, it would be much less flexible. For example, with the design you have now, it doesn't require any database schema change to add another thousand different books or another 20 locations.
If you were to try to put the book quantities inside the Locations table, or the Locations inside the Books table, it would require you to change the layout of the database, and then re-test any code that might be use it.
Thats the most common (and effective) solution. Most frameworks like Django, Modx and several others implement Many2Many relations via an intermediate table only, using foreign key relations.
Make sure you index your table properly.
ALTER TABLE stock_management add index (Book_ID), add index (Location_ID)
That really the best way to do it; you have 9100 independent data to store, so you really do need 9100 rows (less, really; the rows where the quantity is 0 can be omitted.) Other way of arranging the data would require the structure of the table to change when a location was added.
I am quickly putting together a buddy / friends list where a user will have a list of buddies. I will be be using a relation database for this and found the following post:
Buddy List: Relational Database Table Design
So the buddy table might look something like this:
buddy_id username
1 George
2 Henry
3 Jody
4 Cara
And the table for user's buddy lists would look something like this:
user_id buddy_id
2 4
1 4
1 3
My question is how fast would it be if a user had 20,000+ buddies and wanted to pull there entire list in under a second or so. I would be running this on a pretty typical MySql setup. Would there be any key optimizations or db configurations to get this fast?
What does "pull their entire list" mean to you?
I can select 20,000 rows from a large "buddy" table (few million rows) in 15 milliseconds on my computer, but that doesn't include network transit time (both directions), formatting, and displaying on a web page. (Which I presume is the point--a web application.)
You'll need an index that covers user_id, but creating a primary key on (user_id, buddy_id) should do that.
Scripting languages are useful for generating test data. I'm using ruby today.