Profile data in one or many tables in MySQL - mysql

Let´s say I create something familiar to Facebook where the user can add interests to his or hers profile.
One way to do this is to have a field called Interests in the profile table and list the interests ID. So that the field Interests would look like this: 1,4,43,66 where each number refers to an interest in the interest table. I would then have to explode the interest fields using PHP to get each interest´s name.
Another way to do this is to have a third table that looks like this:
profileID, interestID
1 1
1 4
1 43
1 66
Which would achieve the same thing.
I haven´t worked much with databases. I use MySQL. Which is the best way to go? Let me know if you don´t understand.
Thanks for your help!

Your second approach would be the one to go with. It all really depends on your requirements, but the second one is more flexible. With both you can answer the question: "What interests does user X have?", but only with the second one can you answer "What users are interested in Y?". Also, it allows you to do a join, so instead of doing 2 lookups/queries, you can do one.

Related

Mysql query for getting profiles with similar interests

I'm looking for some help with a problem. I've a table with the following columns/fields -
COLUMNS = userName | userEmail | userInterests | .... and other fields
VALUE = userA | userA#email.com | 1,2,10
VALUE = userB | userB#email.com | 15,27,9,7,2
userName(varchar) = the primary key
userEmail(varchar) = user's email
userInterests(varchar) = comma separated numbers for interests. I've mapped these number to their actual value (interests) in PHP script. e.g. 1 - Painting, 2 - Dancing and so on...
Now I'm trying to find the users having the similar interests. The number of interests a user can have can vary. My goal is to find the best match for any user.
Suppose if User A has 3 interests and User B has 5 interests, from which 1 interest is common in both user, so I wanna get the matched user's name. Suppose if there's another user with 2 common interests, then in that case, return that profile. In General, I wanna find the best match (where all interests meet with other user), if not, then second best match (at least have 2 or 1 common interest).
I have already been to this solution but I'm unable to get the desired output. There's only one table, so I can't use the joins as well.
SQL - Finding Users with Similar Interests
Please help me with this, I've been meddling with this from past 2 days and couldn't find the right solution. I tried my best to explain the problem, If I failed to do so, Please let me know and I can elaborate. Thanks
I think the best approach would be to first normalize your database so you don't have an array like structure. This would make this type of query more efficient and much easier to do.
If that's not an option, you can have a look at this answer of how to do this normalization via query to a temporary table and work from there. Once you have a separate table for interests, you can proceed with the solution you already pointed in your question, making a count of the occurences.

MySQL Query <table_name> based on column value return

This may be a ridiculous question with a far more straightforward solution than I am leaning towards here, but I'm hoping someone can give me a good solution!
Let's say I have a database with multiple tables that look something like this:
**table_users**:
id, username, email, password
*example*
testuser, testuser#test.com, 123456
**table_services**:
id, service_name
*example*
0, Shipping
1, Payments
2, Packaging
**table_markets:**
id, market_name
*example*
0, Fashion
1, Food
2, Healthcare
**table_user_attributes:**
user_id, table_name, attr_id
*example*
0, 'table_markets', 1
0, 'table_services', 0
0, 'table_services', 2
In this example, the user attributes table would have user id of 0 associated with 'Food' market and the 'Shipping' and 'Packaging' services.
The reason I have the table name in this attributes column in this example, is these attribute ID's can come from different tables (services, markets in this case) and I need to kow which table to look up the attr_id for.
My FIRST question is - im guessing im doing the table name setup in a very dumb way, is there a better way to locate what table something might be coming from, and then be able to use that in your next query?
my second question is, assuming this is correct, how would I then set up a query to do something like:
look up user, get user id, look up all entries from table_user_attributes with the user id I have received, and then (here's the question part) take the table name and query those with the ids... i.e.:
SELECT table_users.username, table_users.id, table_user_attributes.table_name,
table_user_attributes.attr_id
FROM table_user_attributes
INNER JOIN table_users ON table_user_attributes.user_id=table_users.id
If I'm understanding right, that query would get me the users info, as well as the table_user_attributes associated with that user id, but then I have no idea how I then pull the appropriate services/markets from this info.
I hope that makes sense, it's a strange question - basically im aiming to keep user attributes all in one table, but the ID's that they point to can come from multiple different tables, and I need a way to know from which table each ID associated with the USER id comes from so i can look it up and get its name.
The problems likely enter in:
Database design - I'm quite sure this is not perfect (also this doesn't exist, this is me writing up a theoretical example, I haven't built any tables yet, set primary keys, etc. trying to wrap my head around this issue first.
Query - which will change depending on the design - but if, on the off chance I used what I have above, I don't know how id make that query work.
Probably going about it wrong - so any help is much appreciated!
EDIT
I also realize the easiest (and possibly best) solution is to have a separate table for each thing, like:
table_user_services
table_user_markets
etc - but I guess I just want to check if that is the most efficient solution or if this is a more btree/sql friendly solution.

SQL Stock multiple information in a field or create tables

I'm having conception difficulties to implement something in a database. I have two solutions for a problem, and I was wondering which one is the best.
Problem :
Let's picture a table speciality with 2 fields : speciality_id and speciality_name.
So for example :
1 - Mage
2 - Warrior
3 - Priest
Now, I have a table user with fields such as user_id, name, firstname etc ...
In this table, there is a field called speciality. The speciality stores an integer, corresponding to the speciality_id of the table speciality.
That would be acceptable for users that have only one speciality. I want to improve the model to be able to have multiple specialities for a user.
Here are my two solutions :
Create a table 'solution1' which link the user_id with the speciality_id and remove the speciality field in the user table. So for a user which has 2 specialities, 2 rows will be created in the table 'solution1'.
Change the type of the field speciality in the user table to be able to write down the specialities, separated with commas.
For example 2;3
The problem I got with the second solution is for making foreign keys between my table user and my table specialities, to link them. I may have a bit more difficulties with the PHP in the future too, while wanting to get the specilities for a user (will need to use a parser I guess).
Which solution do you find is the best ?
Thanks.
Absolutely go with your first solution.
Create a third "Many-to-Many" table that allows you to relate a user to multiple specialties. This is the only way to go in your case.
When designing tables, you always want to have each column contain one and only one data element. Think about what querying your second solution would look like. What would you do when you wanted to see all users who had a given specialty?
You might try something like this:
select * from user where specialty like '%2%'
Well, what happens when you have specialties that go to 12? Now "2" matches multiple entities. You could devolve further and try to be tricky, but...you really should just make your data design as normal as possible to avoid all the mess, headache, and errors. Go with Solution 1.
i think the best way is to follow solution1 cause solution2 will end up will lot of complexity later on

Any way to compare/match sentences with only a different word order?

I have 2 MySQL tables , each with address data of companies in it. One table is more recent, but has no telephone and no website data. Now I want to unite these tables into 1 recent and complete table.
But for some companies the order of the words is different,like this:
'Bakery Johnson' in table 1 and 'Johnson Bakery' in table 2.
Now I need to find a way to compare these values, as they're obviously the same company.
I think I will somehow have to split those names first, and then order the different parts alphabetically.
Any chance anybody has done something like this before, and willing to share some code or function?
UPDATE:
I found a function that sorts words inside a string. I can use this to detect name swaps as described above. It's quite SLOW though...
See : MySQL: how to sort the words in a string using a stored function?
If your table is MyISAM you can run this query:
SELECT *
FROM mytable
WHERE MATCH(name) AGAINST ('+bakery +johnson')
This will find all records containing the words bakery and johnson (and probably some other words too).
Creating a FULLTEXT index on the table:
CREATE FULLTEXT INDEX
fx_mytable_name
ON mytable (name)
will speed up this query.
Going back a bit on your solution, you could go with a similar way as modern phones resolve duplicate names conflicts
You present your user with the option, as he finds something suspicious:
Is this a duplicate? Use our [ Merge ] option
You are merging Bakery Johnson, please select the source/original item:
[ Johnson Bakery v ] (my amazing dropdown!)
Everything not already in Johnson Bakery gets ported to Bakery Johnson (orders for example), you may also show an intermediate screen displaying what will be merged, or let the user pick, for example, he wants the address info from Johnson Bakery and orders from both etc
It is not self correcting as you asked, but the collaboration from the users may be more accurate than AI here. I also love low-tech solutions like this so let us know what you ended up doing.

MYSQL: How can I store/retrieve a value based on the 3+ other values in the same table?

Let's say I'm making a program for an English class. I'd like to store data in this way:
ID Object
0 Present Tense
1 1st person singular
2 To Be
3 I am
How can I retrieve the value for ID 3 based on IDs 0-2? The only thing I can think of is:
ID Object FromIDs
3 I am 0,1,2
The problem with this is that I'd have to do a fulltext index and I think this table is going to get pretty large. I don't want separate tables for different types of objects, if possible, because I don't know what I'll end up doing with these objects and I want as much flexibility as possible. I could have a second table relating IDs to each other, but I've only done that successfully relating a column from one table to a column to another.
Thanks in advance!
You need to break the data into different tables. Have a table that stores the "tense"
and another that stores the type "1st person singular".
Can you explain your problem a little more. From what you have I'm not sure if you're trying to go down the path of Entity-Attribute-Value or probably what is more likely is that relational database is not a good fit for your problem; you may need to use some sort of tree data structure. If you update, I can try to provide a better answer.
What I've decided to do is a combination of what was suggested and what I originally thought. I'm going to have a master list with IDs that are auto-incremented and copied to other tables. That way, I have properties of different parts of speech separated, but still have everything relating to everything else.
This is really not a good fit for a relational database. Sorry, you're trying to drive a nail using a screwdriver.
When you have no distinction between an attribute type and a value, you're modeling semantic data. The open standard for this type of data modeling is RDF.
My solution (if you really dont want to break up the table)
**ParentChildTable**
ParentID ChildID
0 3
1 3
2 3
But well, in one table now you have:
-type of tense
-type of person (1st, 3rd....)
-values
So i think it would be better to split, i can see .. .well, right now, 3 tables: values, tensetypes, personetypes and relationship table (value-value for tense/person)