Hey all,
I am setting up a PHP web app that will make use of subdomains for accounts. I am storing subdomains in a MySQL table with the following fields:
subdomain_id | owner_id | name | date_created
owner_id maps back to user_id in the user table The user table has the following fields:
user_id | email_address | etc...
Now I am trying to figure out what is the best way to store which users have access to which subdomain. Is the best to set up another table with the following fields?
id | subdomain_id | user_id
That would contain data such as the following (showing user #6 has access to subdomains 4 & 7):
id | sudomain_id | user_id
1 | 4 | 6
2 | 4 | 23
3 | 7 | 6
Is there a more efficient way?
That is the correct way to model a many-to-many relationship, but the id column is entirely unnecessary. You don't need to give every table an artificial identifier. The primary key of that table is simply (subdomain_id, user_id).
Related
I made a firm to add a user to my database now I want to have two tables. One table keeps track of the languages the user knows and the other table the design software the user uses.
Would I create 3 tables (profile, languages, software) each with an I'd field and when I add a user add a row to each table?
As you begin to add several many-to-many relationships, you need more tables to 'link' the information together. Here's how I would tackle the problem:
Note The IDs should all be unique indexed columns. Consider using AUTO_INCREMENT.
Table 1: Contains user's profile information
| ProfileID |UserInfo |
|=======================|
| 0 | Info |
|-----------------------|
| 1 | Info2 |
|-----------------------|
Table 2: Stores the possible languages
|LanguageID |LanguageName|
|========================|
| 50 | Python |
|------------------------|
| 51 | Java |
|------------------------|
and so on...
Table 3: Stores the Profile links to the languages
|ProfileID |LanguageID |
|========================|
| 0 | 50 |
|------------------------|
| 0 | 51 |
|------------------------|
| 1 | 50 |
|------------------------|
Every time you wanted to add a language to a user's profile, you'd create an entry in this table.
You would add two more tables for the software a user knows. One table for all the possible types of software, and another to store the links.
When you want to retrieve the information, you would do an operation such as the one below:
SELECT * FROM Table3
LEFT JOIN Table2
ON Table3.LanguageID = Table2.LanguageID
WHERE ProfileID = [TheProfileIDToSearch]
This structure uses JOIN to link tables together to return information from several tables at once. Here is a W3Schools quick explanation about SQL JOINS.
I'm building a multi-tenant application using Symfony3, Doctrine and PostgreSQL.
I want that each entity have two primary keys: tenantId and entityId. This way, each tenant has each data with id's starting with 1.
So, user 'Xyz' from tentant 1 is http://example.com/users/1, and user 'Zzz' from tenant 2 is also http://example.com/users/1. The tenantId is stored in the session, so it's not represented in the URL (and yes, I know that this is incorrect RESTful).
I already know how to work with composite keys with Doctrine, adding #Id annotation to all the fields, but I don't know how to generate these id's.
Is there any automatic way to have this behavior, or I need to create a custom generator in Doctrine and find the MAX(id) + 1 for the given entity, using a WHERE tenantId = :TENANT_ID?
Thanks for your help.
Example of what I'm looking for:
Tenants table:
tenantId | tenantName
1 | First company
2 | Second company
Users table:
tenantId | userId | userName
1 | 1 | Mr Foo Bar
1 | 2 | Mrs Bar Foo
2 | 1 | Mr John Doe
2 | 2 | Mrs Mary Doe
As you can see, the primary key of the users' table is a composite key (tenantId, userId). What I'm looking for is for a simple, automathic method to generate userId. In a table with only a PK, this method can be a simple generator or a SERIAL field, but as this is a composite PK, I need that the userId value depends on the tenantId field.
I'm not sure why I'm struggling with this it seems like a very simple concept. So my struggling makes me think that perhaps my data modeling needs another component...
I'm using Laravel 5 and am trying to define some model relationships. BelongsTo,HasA, etc. Before I can write the code, I need to at least conceptually understand what type of relationship I'm creating.
I have an application to where users can send people referral links, if a person clicks on the link and signs up, their user record makes note of the code that referred them. This way I can trace back and see who referred a particular user. But a referral is NOT necessary to sign up
Tables:
USERS
+----+-------------+
| id | referral_id |
+----+-------------+
| 1 | 1 |
| 2 | null |
| 3 | 2 |
+----+-------------+
REFERRALS
+----+---------------+---------+
| id | referral_code | user_id |
+----+---------------+---------+
| 1 | 12345 | 2 |
| 2 | 54321 | 2 |
| 3 | 99999 | 2 |
+----+---------------+---------+
USERS.REFERRAL_ID references REFERRALS.ID
and
REFERRALS.USER_ID references USERS.ID
But what kind of relationships are these?
The only one that seems obvious to me is that REFERRALS.USER_ID belongs to USERS.
But what about USERS.REFERRAL_ID, saying it belongsTo Referrals doesn't feel right, as that record isn't required and I don't feel like it 'owns' the user by any means. Saying it hasA referral doesn't feel correct either, as again the user doesn't own or even require the referral.
I guess what is confusing me is that REFERRALS is an optional entity.
How should I conceptualize the relationship between USERS.REFERRAL_ID and REFERRALS.ID?
Is it bad to have this sort of "circular reference"? Would I be better off creating a pivot table?
No need to add any reference to the Referrals table in the User table, you already have that relation defined in the referral table ( user_id column )
Further reading: https://en.wikipedia.org/wiki/Database_normalization
The Relationship is
USER has many REFERRALS
REFERRAL belongs to USER ( inviter )
REFERRAL belongs to USER ( invitee )
Modify your REFERRALS table
+----+---------------+---------+------------+
| id | referral_code | user_id | invitee_id |
+----+---------------+---------+------------+
| 1 | 12345 | 2 | 1 |
| 2 | 54321 | 1 | null |
| 3 | 99999 | 3 | 1 |
+----+---------------+---------+------------+
user_id is the id of the user that sends the invitation
invitee_id is the id of the user that accepts and registers
invitee_id column is nullable() and will contain the id of the invitee from users table when they join.
Think of it as a JOIN table between inviter and invitee.
Here is my pivot table project_group:
+-----+----------+------------+----------+---------+
| ids | group_id | project_id | admin_id | user_id |
+-----+----------+------------+----------+---------+
| 4 | 115 | 1 | 1 | [3,4,5] |
| 5 | 115 | 2 | 1 | [5,2,1] |
| 6 | 115 | 3 | 1 | [1,3,6] |
This table represent group linked to the projects....user_id is which users can see projects/group... Is there any way to display correct projects/group only to the users defined in user_id?
Also content in user_id field can be changed....
The best way to handle this would be to first normalize your database. Storing comma separated lists in a cell is allowed, but generally bad practice, as explained in this question.
If you can have multiple users per project, you should have a linking table with a column for project and a column for user, like this:
project_users:
| project_id | user_id |
and you can make (project_id, user_id) a composite primary key.
That way, you can select the users for a project (say, project 1) like this:
SELECT user_id
FROM project_users
WHERE project_id = 1;
Once you have these, you can display the project data only to users whose id is returned in the above list.
I have built an SQL Fiddle that helps demonstrate this visually, if it helps.
It is good to note that this proper normalization gives the opportunity to a lot of useful data as well, as it becomes easier to search for users by project, but also you can search for project information based on a user.
I am a high school student learning PHP and MySQL. I am trying to create a simple photo sharing site that allows a user to sign up and start uploading images. Each user has a profile that shows all of their pictures.
I currently only have one table, called "users": username, email, password
How should I set up a table for the pictures? And how do I link to each picture's filepath?
Thanks
On your user table create a column called Id (this should never change)
You normally use something like an INT AUTOINCREMENT number for this so the database allocates it automatically, and this should be marked as the PRIMARY KEY
Create a table called photos
Table photos
Id = autoincrement primary key
UserID = int (you can set this up as a foreign key, but to keep it simple, just make it indexed)
Title = varchar
Info = varchar
Filename = varchar
Table Photos
Id | UserId | Title | info | Filename | (add other columns to suit)
------------------------------------------------------------
1 | 1 | Duck | xyz | duck.jpg |
2 | 1 | Cat | xyz | cat.jpg |
3 | 2 | Mouse | xyz | mouse.jpg |
As you can see from the data above
Photo 1 and 2 belong to user 1
and photo 3 belongs to user 2
To select all the photos for username 'bob' you would do something like this
SELECT Photos.Id, Photos.Filename
FROM Photos
JOIN Users ON Photos.UserId=Users.Id
WHERE Users.username = 'bob'
The first question is where are you storing the user's photos? I would recommend this:
Table (User's):
Username | Password | Email
---------------------------
user1 | fdgfdg | fdfgdf
user2 | ffdgfd | fgdfgf
user3 | dgfdgg | fgdgdd
Then, whenever a user signs up, create a folder with that user's name and a subdirectory titled photos.
Create a Table for Each User.
Table user1
Photo | Title | info
----------------------------
duck.jpg | My Duck! | fgdf
cat.png | Le Cat | dfgd
Then, when a user logs in, list all the Titles and link them to the photo dynamically.
So I would be
My Duck --> http://mysite.com/user1/photos/myduck.jpg
Where user1 would be the logged in username, the photos would automatically be added and myduck.jpg would be pulled from the database.
However, this opens up two holes:
- Hotlinking
- If someone knows the username and photo title, they can access the photo without being given permission.