Need to mention first that i'am a newbie in PHP/MySQL. I would like to hear from you, from your experience, what's the best way or approach to deal with a table rows such as tbl.users for future development and compatibility with other features on web application ?
Currently, I have a tablename users like shown below:
id catid firstname lastname username email password status image
14 21 Joe1 Doe joe1.doe jd#m.cc sha512ed 1 pic.jpg
15 17 Joe2 Doe joe2.doe jd#m.cc sha512ed 1 pic.jpg
18 22 Joe3 Doe joe3.doe jd#m.cc sha512ed 1 pic.jpg
33 20 Joe4 Doe joe4.doe jd#m.cc sha512ed 1 pic.jpg
Now when I'm done with users, I would like to create an basic e-commerce with products, and clients, etc... And here comes the question, how should i work it out without need to recreate a tablename clients ?
Would be it clever to add a new column to tbl.users such as attributes and store some attribute there to extend the functionality such as client = 1 or something like that ?
So it will become like this:
id username ... attributes
14 joe1.doe ... rememberme = 1, client = 1
15 joe2.doe ... rememberme = 1, client = 0
18 joe3.doe ... rememberme = 0, client = 0
33 joe4.doe ... rememberme = 1, client = 1
Meaning that user.id = 14, 33 will become clients, and will be displayed appropriately in e-commerce component ?
If it's ok, how should I store that attributes information ? I guess the way I made it is not right.
i learned that its better not to mix tables, i mean if you have users table, dont add cart stuff info into it, will make it hard in the future to read the table, and you wont understand why you added that info into the users table.
the question is what clients are? non users, just visitors or users as well?
if they are users, you should make clients table, with unique id, user_id, client_id,
very basic table that will allow you to get the number of clients that user have, and in the future you can add more columns into the table like, items_bought and much more, you should do that if a user will get multi clients, witch i think is the case.
but if each user will have 1 client (i dont think its the case), you can add column into the user table client_of but then you can't store multi clients, only one.
so for the future, dont mix tables, each "theme" should have its own table, in my opinion of course.
P.S
you have many options when you have 2 tables, so dont add the same attr to both of the tables, add all the info of the users to the users table, if you need the user info of a client, get his id from the client table and then get the info from the users table, but if you need an info that only clients need, then add that attr to the client table.
edited:
quick example :
users table:
`id` `first_name` `last_name` `username` `password` `date`
`1` `alex` `maya` `alex.maya` `pass12` `yesterday`
`2` `bob` `smith` `bob.smith` `pass43` `today`
the client table:
`id` `user_id` `client_id`
`1` `1` `2`
`2` `2` `1`
this tables says that alex bought from bob and bob bought from alex, lets say i'm bob, and i want to see the info of the user that bought from me:
$sql = "SELECT client_id FROM clients WHERE user_id = {$user_id}"; // output = the id of the users who are his clients.
`
First, I recommend you read a bit more about the design database, particularly on how to obtain best tables by normalization.
You will see that you should first design your database graphically, making a simple diagram with entities and relations between them.
As object-oriented programming, you want to have more general tables with minimal data common to several types, for example a person table which you can then specialize in Customers, Vendors, Employees, etc., if your design requires it.
The next step is to ask how these entities are related, that way you can see that you need a new table for the relationship or simply add a unique ID in the other table.
Here I leave a link to learn the issues that I mentioned to you earlier: http://www.sqlcourse.com/index.html
Related
I have an existing website, that doesn't use any specific framework. This project is much older and is slowly being evolved, which is somewhat of a nightmare really.
Currently, I am trying to implement a better solution to current users to have 'assistants' to their accounts.
The current data resides like this (users & contacts tables):
**users table**
userId, email, password...
1 test#test.com, pa$$word
2 ass#test.com, pa$$word
**contacts table**
contactId, userId, fName, lName...
1, 1, john, doe
I am trying to figure out how to modify my site to enable userId's (1&2), to be able to access this contact.
Instead of starting over, any direction or samples that I could glean from on how to solve this issue of mine? Any help would be greatly appreciated.
Remove the userId column from the contacts table and create a new table contacts_users with two columns, contactId and userId.This is called a PIVOT TABLE and allows many-to-many relationships like what you are describing.
I have to maintain the data of friend list of friends who liked a particular category post. And this may be at any level. For eg.
if a friend of A who is B like a wanted post. then I ll maintain the record of A’s friends and B’s friend. Basically my requirement is
If user visit my product site I have to tell him/her that you're following friend already visited the same and they actually recommend you to use this and to build confidence that you are on the right way as your friends are also using it. I also want to suggest A that C who is the friend to B is using this product since this time and C suggest to many for using it.
I know this logic is already implemented in good sites.
I am just a starter. So pls suggest me the database for backend and required things for frontend.
Specially this question is to maintain the record on database. So I am asking for the database what should I use not how should I implement that would be next step.
As I am planning to use Graph database for it. In graph either bigdata or Neo4j.
Your ideas are most welcome and will be appreciated. Thanks
I hope my logic may takes you few steps forward
Initially we have to maintain the mutual friends records
foe example
id mut_id
1 2,3,4
Here 2,3,4 are your friends
next we need to maintain the records who has purchased/visited
prod_id buy_id
1 2,1
Now suppose 3 id wants to buy or visit site then we can show that your friend already visited or buyed product
Friends' relations is a classical many-to-many scheme. You need two tables to implement this:
1. A table with personal data, such as name, email etc. (could be more complex like person-properties relation)
2. A table with friends' retaionships data, usually it contains ID pairs of friends that relation is representing and some data about relation itself, such as category (friend/family/classmate etc) , level of affinity (if >0 it means positive relation, <0 negative such as enemies) and so on. Assume first ID is a person this relation belongs to (and can be maintained by), second ID is a person this relation applies to. Usually such kind of tables is constrained to pair of IDs to be unique, so nobody will be able to add same person as a friend twice
Here is some sample:
CREATE TABLE person
(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255),
email VARCHAR(255),
PRIMARY KEY (person_id)
);
CREATE TABLE relationship
(
id_person INT NOT NULL REFERENCES person(id),
id_person_related INT NOT NULL REFERENCES person(id),
id_category INT REFERENCES relcategories(id),
affinity INT,
PRIMARY KEY (id_person, id_person_related)
);
Note that affinity and id_category fiels are optional and last one requires table relcategories with INT id field to be create first
Visits of one friend to another can also be stored in relationship in a separate field
I'm developing a site that will be a subscription based service that will provide users several courses (videos) based on whatever they signed up for.
Currently I was considering the following db structure
Users
------
email | pwd | subscription_date | expiration_date
Unique Key would be "email"
Course_Subscription
-------
email | calculus_1 | calculus_2 | physics_1 | physics_2 ... | Nth course
the number of courses offered will probably start at approx 15, and gradually increase overtime. Also the course subscriptions will be boolean value of TRUE/FALSE
then a table for each course as follows:
Calculus_1
----------
id | title | description | video_url |
there could be more than 20 chapters in a single course.
A little bit of info on authentication process - it will go userlogin ---> course subscription ---> course chapters. Where both user login and course subscription will be verified against the email address. The videos will also be checked against the subscription table prior to being played.
My questions are:
Is this the best way to structure this? Or are there better alternatives?
Would this cause any problems in terms of performance? Or would it not be noticeable?
Here is a sample of a php script that I'll use to authenticate and populate the html
$sqlSubscription = "SELECT * FROM course_subscription WHERE `user` = $user && `calculus_1` = TRUE";
$subscriptionResult = mysql_query($sql) or mysql_die($sqlSubscription);
while ($row = mysql_fetch_assoc($subscriptionResult))
{
$user=$row["email"];
$calculus_1 =$row["calculus_1"];
if($user==1 && calculus_1==TRUE)
{
$sql = "SELECT * FROM calculus_1 ORDER BY `id`";
$result = mysql_query($sql) or mysql_die($sql);
if (mysql_num_rows($result) > 0)
{
$data = array();
while ($row = mysql_fetch_assoc($result))
{
$data[] = $rows;
echo "HTML THAT WILL CREATE A LIST BASED ON TABLE INFO"
}
}
}
}
The above code is for the menu that will populate a list of chapters based on their subscription. I know the code isn't perfect, I'm still working on it - but I wanted to nail down the structure of the db first now that I have a fairly decent idea of how I'll be accessing the information.
A design that requires changing that data model by adding new columns and tables just to add new data, like courses, is not a good design. You should have a table with courses and a table for subscriptions.
Also, email is not a very good choice of primary key. The primary key should never change, but people may want to change their email address. For this reason an autoincrement number is often used as the pk.
A schema that takes these suggestions into account would look like this:
students courses subscriptions
--------------- ----------- -------------
student_id course_id subscription_id
email name student_id (foreign key to students table)
name description course_id (foreign key to courses table)
subscription date video_url
You may have to adapt this to your specific requirements. For example the subscription expiry date: If the expiry date depends only on the the student and not on the course it can make sense to have it in the students table like you do now. But, if a student can subscribe to different courses at different dates and you want the possibility of having a different expiry date for each subscription it should be in the subscriptions table instead.
Your design would be horrible to maintain over time. What you are proposing means that every new course would add one more column to your course_subscription table, and a new table to the database.
I'd go for a structure where you have a user table, a course table describing the individual courses (including the video url, etc.), and a user_course_subscription table, that basically consists of a user_id and a course_id, and the start-date and end-date.
This removes the requirement of having a single column for every course, while still allowing you to add students to multiple courses. It's an example of the pretty standard "many to many" relationship, where the junction table (in this case user_course_subscription) just adds the link between the other two entities.
I have a forum website that I'm building myself. I'm planing to add group section into my website.
Users will be able to create groups. And manage by themselves. and then the creator should add moderators to the group.
How should I store this moderators? Should I create new table like this:
group_moderators
ID - GroupID - UserID
or should I directly insert into group table
ID - GroupName - Moderaters
1 - Tech - 5, 7, 9 (These are User IDs) then I can separate them with PHP.
It depends on your plan:
if you are planning to have multiple moderators per group then you
have to create a new table for moderators
if you are planning for only 1 moderator for each group then you can add a new column to the group table
UPDATE
Multiple IDs in 1 field is not a good idea at all, it will cause a lot of headache if you want to select, update, join, delete moderators.
First option because it'll be easier to delete or update the mods and it''ll be eaiser to update the table if you intend to give different powers to different mods in future ..
For Ex
ID - GroupID - UserID - Power
1 14 1 Mod
2 14 3 Super-Mod
Say I have a table customers with the following fields and records:
id first_name last_name email phone
------------------------------------------------------------------------
1 Michael Turley mturley#whatever.com 555-123-4567
2 John Dohe jdoe#whatever.com
3 Jack Smith jsmith#whatever.com 555-555-5555
4 Johnathan Doe 123-456-7890
There are several other tables, such as orders, rewards, receipts which have foreign keys customer_id relating to this table's customers.id.
As you can see, in their infinite wisdom, my users have created duplicate records for John Doe, complete with inconsistent spelling and missing data. An administrator notices this, selects customers 2 and 4, and clicks "Merge". They are then prompted to select which value is correct for each field, etc etc and my PHP determines that the merged record should look like this:
id first_name last_name email phone
------------------------------------------------------------------------
? John Doe jdoe#whatever.com 123-456-7890
Let's assume Mr. Doe has placed several orders, earned rewards, generated receipts.. but some of these have been associated with id 2, and some have been associated with id 4. The merged row needs to match all of the foreign keys in other tables that matched the original rows.
Here's where I'm not sure what to do. My instinct is to do this:
DELETE FROM customers WHERE id = 4;
UPDATE customers
SET first_name = 'John',
last_name = 'Doe',
email = 'jdoe#whatever.com',
phone = '123-456-7890'
WHERE id = 2;
UPDATE orders, rewards, receipts
SET customer_id = 2
WHERE customer_id = 4;
I think that would work, but if later on I add another table that has a customer_id foreign key, I have to remember to go back and add that table to the second UPDATE query in my merge function, or risk loss of integrity.
There has to be a better way to do this.
I got here form google this is my 2 cents:
SELECT `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE REFERENCED_TABLE_SCHEMA='DATABASE'
AND REFERENCED_TABLE_NAME='customers'
AND REFERENCED_COLUMN_NAME='customer_id'
add the db for insurance (you'll never know when somebody copies the db).
Instead of looking for a column name, here we look at the foreign keys themselves
If you change the on delete restrictions to restrict nothing can be deleted before the children are deleted/migrated
The short answer is, no there isn't a better way (that I can think of).
It's a trade off. If you find there are a lot of these instances, it might be worthwhile to invest some time writing a more robust algorithm for checking existing customers prior to adding a new one (i.e. checking variations on first / last names, presenting them to whoever is adding the customer, asking them 2 or 3 times if they are REALLY sure they want to add this new customer, etc.). If there are not a lot of these instances, it might not be worth investing that time.
Short of that, your approach is the only way I can think of. I would actually delete both records, and create a new one with the merged data, resulting in a new customer id rather than re-using an old one, but that's just personal preference - functionally it's the same as your approach. You still have to remember to go back and modify your merge function to reflect new relationships on the customer.id field.
At a minimum, to prevent any triggers on deletions causing some cascading effect, I would FIRST do
update SomeTable set CustomerID = CorrectValue where CustomerID = WrongValue
(do that across all tables)...
THEN
Delete from Customers where CustomerID = WrongValue
As for duplicate data... Try to figure out which "Will Smith, Bill Smith, William Smith" if you are lacking certain information... Some could be completely legitimate different people.
As an update to my comment:
use information_schema;
select table_name from columns where column_name = 'customer_id';
Then loop through the resulting tables and update accordingly.
Personally, I would use your instinctive solution, as this one may be dangerous if there are tables containing customer_id columns that need to be exempt.