Private Messaging System with 3 different users tables - php

I have three different users tables, and I would like to know what is the best way to create a private messaging system for them to communicate.
I tried to create it with a simple db scheme:
id (int)
from (int)
to (int)
subject (varchar)
message (text)
timestamp (timestamp)
read (bool)
deleted_to (bool)
deleted_from (bool)
But complications instantly arised because of the three users tables, where user IDs in table A can have ID = 1 and another user in table B can have ID = 2
Any ideas on how to create a better DB scheme? Thanks

use "model" column with varchar type to save which user model the user comes from.
this way you can have several entries with "2" for example. model + user_id then has to be unique.
e.g.:
User1 3
User1 5
User2 3
...

A hackish solution would be to create a hash for every user and store it in one table to uniquely identify any users. Then, using the hashes, figure out which message was sent to which user.
It most certainly is not a great idea, because it generates unnecessary overhead sending several queries to the database. If possible, create a table to hold all users and using one-to-one relationships create tables for entity specific fields. Your authentication methods would be stored in the user table. Post authentication your system would know, which tables to join together for the required data as described in that single user table.

You could add two fields in your table to store the "table" related to the from and to.

Dunno what kind of db you are using but this problem could be solved easily with table inheritance.

Related

Use one-to-one MySQL Relation or not?

I have user table, and I need to expand it with author and partner data. Should I put additional columns in same table or create 2 more tables (user_author and user_partner) with one-to-one relationship ?
Tables and columns are simplified for example.
user
id
name
email
password
avatar
is_active
user_author
user_id => user.id (PK, UNQ)
description
amount_per_text
max_text
is_active
user_partner
user_id => user.id (PK, UNQ)
name
description
image_logo
is_active
User cannot be both author and partner. And then I can have classes like User.php for normal users, UserPartner.php and UserAuthor.php which extends User.php class.
Does it make sense or should I just put those columns in user table ?
Both approaches are valid and frequently used.
The normalization theory of a relational schema would not allow to put all the data in a single table for reasons of data consistency. This would favor a multi-table approach.
In the single-table approach you'll end up with a lot of empty (null) fields in every record in the table.
When using multiple tables, however, you may have to perform one or two joins just to find out if a record is a partner or an author. Hence, from a performance viewpoint, the single-table solution is preferrable.
In both cases, you could include an extra field, e.g. "recordType", in user to quickly and easily discriminate between the different types of records. This will give the best possible runtime performance.

Mysql design. Two types of users, two different profiles

I want to design a DB which will be connected to PHP Application. In the app there are two types of users: company and person. Some functionality like adding articles will be done by both so in other tables there are author_id columns. So firstly I decided to create user column.
That's easy: id, username, password, role, active, created where role defines whether user is person or company.
Now I want to add profile table or profile tables depends on what you'd suggest (joined with the previous table by adding profile_id column there).
Both roles have different fields, which are required during registration.
The easiest thing would be to create one table with all required fields for both roles, allow them NULL values and in the PHP app (made in Yii Framework in this case) define requirements for each role in models.
The nicest thing would be to create separate tables for both roles BUT the questions is how to connect these two tables to one table using Foreign Key? Is it even possible. I know I may omit foreign key creation then based on role choose table, and from that table choose profile_id.
Or maybe you have another solution to my problem.
Thanks in advance for replies.
Adrian
You need an intermediary between the page and the database to assign the user to a group that has specific privileges. It's usually accomplished with a user-group-role design.
You can have a table for users system info (username , pass ...), and another for users profile (firstname , birthday ...), and another for groups(superuser , ...).
where user table can have multiple groups: user:one->group:many
user can have one profile user:one->profile:one
I think this is a decent solution.

User's custom profile fields

I am currently working on a system that would allow users to add additional custom fields for the contacts that they add.
I wondered what is the best and most efficient approach to add such ability?
Right now what I was thinking was to have 1 table per users (with foreign keys to a "main" contacts table) and then adding a column for each custom fields that the user adds (since I don't expect to have more then 100-200 users per database shards [sharding is easy since every users never see each-other's content in this system]), although I am not 100% sure that this would be the right solution for such problems.
Maybe you could try to have one separated table to store a reference to the user, plus the field name and value, this way you will be able to have lots of custom fields.
If you go with Boyce-Codd, you separate the information and store them into a table.
Means one table for all users with a foreign key.
One table per user would lead to hundreds or more tables with possible repeated information.
You need to have one table named USERS that stores the id of a user and fixed info you might want. Then, you could have a CONTACT table, that stores the type of contact user might create, and one matching table USER_CONTACT that matches the user unique id with the id of the contact that was created.
With this, you could have advanced data mining on all the information stored, like nowing how many contacts each user created, who created more, etc...

Is it better to have two separate user tables or one?

My web app is going to have two types of users that are 100% different - in fields, functions, and purpose on the site. The purpose of one type of user is to post blogs, and the purpose of the other is to read them and "follow" the posters.
The ONLY stuff they have in common are the need for an id, email, password and a couple other bits of meta data such as date joined, etc.
Should I attempt to stem them from the same account table, or make one table for each?
NOTES
-One potential thing to think about is that, to prevent user confusion, I think emails between the two types of accounts should be unique.
-Readers and Authors will have different sets of data that will need to be stored about them aside from the normal "account" meta data.
I would separate them.
TABLE User {
id
email
password
salt
created
modified
}
TABLE follower {
user_id
...
}
TABLE author {
user_id
...
}
Over time your application will grow. Perhaps now you have two destinct roles - but it may change in the future. You may have authors that also follow other authors, or followers that are "upgraded" to authors. You might also start adding other "roles" and want something like this:
TABLE user_role {
user_id
role_id
}
TABLE role {
id
name
}
Define "user". If a user is somebody who has registered him or herself on your site, using an e-mail address, password and nickname, and who can log on, then stick everyone in the users table.
The things users can or can not do on a site does not differ for a user. It's their permissions that are different. Map permissions to users in a separate table. Don't create a table for each type of user.
Otherwise, when you're adding a new kind of permission in the future, you don't have to add a new table for that type of user (and alter all (sql) code that handles with users: logging in, resetting passwords, and so on). You just add a new type of permission, and map that to their respective users.
it will save you allot of work to just have one table and have a single column in the table that defines which type they are .
No, make one table for each. It will be easier to manage, it'll be scalable

which database type are good for arrays?

i want my database to support one company haveing many users how can i do that? exampleusers table(UID,username,password)company table(CID,companyname,usersthatistheownerofthecompany) how can i do that? what should i do ? should i make an array in php like 1241,423,4123 *uid's that will be inserted on usersthatistheownerofthecompany row ? or is there any better idea ?
If you want each user to have one (and never more) company, you should have :
user table
uid
username
...
company_id
company table
company_id
company_name
...
Then, user.company_id would be a foreign key, that references company.company_id.
And, then, you store :
One line in user for each user
Referencing the id of the right company for that user
which is the company_id of the right line in the company table.
And one line for each company in company
There is no user's related information stored in the company table -- and as each user "points" to a company, a company can have several users.
Storing data as an array like you suggested is definitely not quite a good idea -- just not the way a relational database works.
If each user can have several companies, and each comparny can have several users, you'll have to add a third table (a join table), that will indicate, for each user(s), to which company(ies) they are attached to :
user table
uid
username
...
company table
company_id
company_name
...
user_company table
uid
company_id
In this situation, there is no user-related stuff in the company table, and there is no company-related stuff in the user table : the link between those is in the user_company table.
Of course, user_company.uid will be a foreign-key to user.uid ; and user_company.company_id will be a foreign-key to company.company_id.
There is a better idea - it's called a cross-table join. What you do is you create a third table, which contains two columns. In those two columns you store the primary key of the tables you're connecting to eachother.
The idea is that you're creating a relation between a company and a user. In a relational database, relations are indicated between tables by using foreign keys.
Of course, this only applies when you want to connect multiple users to multiple companies (an "M-N" relationship). If you want to connect multiple users to a single company, simply add a column for the company id to the user.
Any relational database is a good way to go. Have a look at MS SQL or MySQL.

Categories