CakePHP using a table to show relation between two tables - php

So I was building a cake project with a coworker the other day and he used a table in the database (users_credentials) to create a link between two constant tables (users and credentials.) When I tried to duplicate that result with a project I'm working on alone, it isn't working. Can anyone throw me a bone? I just need something to Google or a name or something.
Thanks
Justin

I think you want to connect a user to some credentials? What you can do is give each row an unique number (primary key) and combine those two keys in another table.
You could search google for "foreign keys and primary keys" I think, or search for an ERD (Entity-relationship diagram).

You will likely need to just do a join of the 3 tables. The CakePHP user guide offers some help on how to do that assuming you've got your application hooked up to the database correctly. It looks like Cake also does some of the heavy lifting for associating your Models with one another as well as documented here. I'm more familiar with CodeIgniter's syntax, but the basic idea is the same:
select something from users
join users_credentials on user id
join credentials on credential id

Related

What is the point of making relation in phpmyadmin database designer?

I understand some basics about relational database. But I don't get the point of making relation through phpmyadmin designer. What is the benefit there when I have to query any related table with another table's content ID?
When I make any query to select post where user_id=1, is there any way to make it like that, I will select from user_list where id=1, and I don't have to make another query to table posts?
To answer the first question: It documents the relationships for reference, and most designer applications will generate constraints enforcing those relationships.
To your answer your second question, no. If you only want information from posts, there would be no reason to involve users_list unless it relied on information from there, such as wanting to know "posts made by any users with the first name 'bob'"; in which case you would use a join. But if you already know the id for the user, there is no reason to involve users_list.

Multi databases vs. composite primary key - Laravel Saas app

So. I'm building a multi-tenant Laravel SaaS web-app, and am a little stuck when it comes to the database design. I have been searching around trying to find a solution, but i really can't decide on which one to go with. I really hope some of you with more experience and knowledge than me can come up with some advice. Sorry about the long post, but i hope you’ll hang in.
Problem:
In the app my users will be importing data from an external database of their own (with a know schema).
E.g.: I will be importing products with realtions to categories. The easiest way would just be to import the external product_id to the new primary key of the product.
BUT as the users product_id’s will probably conflict, i will have to assign each product with a new primary key, while still keeping the external product_id for reference when syncing back to the external db.
E.g.: external product_id will be ext_product_id and i will assign a new product_id as a primary key.
As of now i can think of 3 ways to do this:
Solution 1 - Single database with new primary keys:
So if i import a list of products and categories i will have to save each external product_id as ext_product_id and assign a new primary key to the product. I will then have to query the categories ext_category_id = the products ext_category_id and then create a new relation with the new primary key product_id and primary key category_id.
These looping queries takes forever when importing several thousands of rows, and some tables has 4 different relations which mean a lot of “ext_” columns to keep track of and sync.
Solution 2 - composite primary key:
As each user will have no reference to an external database i could create composite keys consisting of the tenant_id and e.g. the external product_id. This would allow my to just batch insert the external data with a key prefix consisting of the tenant. This way the relations should be working "out of the box".
But Laravel doesn't support the feature as far as i understand? Any ideas?
Solution 3 - multiple databases:
To create a separate database for each tenant would probably be the best solution performance and sanity wise (to begin with), as i would just be able to copy/batch insert the external database, and the relations would be working right away.
But i'm really worried about the scalability of this design: How many databases would i realistically be able to manage? Say i have 1000 or even 10000 customers?
What if i want to add a column in an update - would i be able to perform some kind of loop-migration to all databases?
I really hope that some of you can help me move on with this as i am stuck and have no experience with solution 2 and 3.
Thanks in advance!
I would personally go for Solution 2 as that is probably the safest.
Solution 1 should be ruled out since you don't want to confuse the users of your application by modifying their data.
Solution 3 would probably be a pain to maintain and is more likely to fail (back-end of the application) + you will lose all track of whose database it is.
As for solution 2 that seems to me like the ideal one:
I don't know what you are using (PHPMyAdmin or another type) but basically what you want to do is have 2 columns:
table
id(PK, AI) original_id(PK)
and then just the rest of your table.
Like this you will have your own Auto Increment (AI) key and you won't get any conflicts from your users since the combination of your auto_increment and that of the user is going to ALWAYS be unique.
for example:
user1:
id = 1 | original_id = 1
user2:
id = 2 | original_id = 1
This still works because the combination is unique.
Another pro of using this composite UID is that you can still use your own id to perform queries or actions on the desired rows etc...
Hope this helps
There are many things to consider when choosing an architecture, but from what you've described, I suggest you use Solution 3 because:
as you've very well pointed out, it's the best solution performance wise (especially if you end up with a lot of customers) and you won't need to handle the overhead of having large amounts of entries for all customers in one table
you have a clear database structure where only the necessary relations are present, no extra fuss to track different customers
As far as maintaining and updating database structure, you can can create Laravel Commands to automate running migrations for multiple databases. You can have a look at this answer to get an idea of how you could do that (although that situation is a little different from what you'll be needing, it offers some insight). Also anything else that needs to be handled in batch can be automated via Laravel commands or other scripts, so the amount of databases should not hinder maintenance.
A more modern way of doing this is to use UUID as primary keys. If you also,
when you import data have a source_uuid, import_time etc, in the table you can bookkeep all import (and export).
It might be hard to convince all parties to use UUID - but that is the best way go.
/gh

When using cakephp habtm, do I have to create relations in MySql too?

Or is it enough to have just the relations defined in the model. I have been trying to connect tables users and groups and got only to a point where only last connection in array got saved ...
Just to add, I am using table users_groups as a join table. This table tas fields user_id and group_id. Find all works like a treat.
All you need to do as far as your database is concerned is to make sure you're using the correct table name and field(s). Then, as long as you have your model associations set up correctly, you should be good to go.
In your case, your table should be 'groups_users', not 'users_groups' (they should be in alphabetical order).

Generic Admin Site in Php / Mysql

i am building a auto / generic client admin panel for Mysql Databases , it only takes a connection string and the system Dynamically creates all the The forms for all the tables with validation and Creates ALL CRUD operations for the tables in the database , i finished all that and did it OOP but the last thing to do is get the tables and Fields Relations Dynamically , so how can i implement that ?
Best Regards,
Look at the MySQL SHOW TABLES... and SHOW COLUMNS... statements.
If you're looking for foreign key constraints you can query INFORMATION_SCHEMA.TABLE_CONSTRAINTS and INFORMATION_SCHEMA.KEY_COLUMN_USAGE.
Both gonna help you out:
SELECT * FROM information_schema.KEY_COLUMN_USAGE WHERE table_schema='<database>' AND REFERENCED_COLUMN_NAME IS NOT NULL
Prints you all foreign keys of a specified database.
Can easily be used for any case of working with your foreign keys.
Might also be helpful:
Foreign key constraints missing from SHOW CREATE TABLE output

Is it a bad idea to connect two databases like this? How can it be done?

I am currently using Simple Machines Forum on my website, and users both register AND login using their forum account on my website. The smf_members table contains fields such as:
id_member | member_name | date_registered
What I am trying to do now is extend this to add more custom fields and connectivity on my site. I want to use the id_member field for many things:
For example, I want a user (an entry in this smf_members table) to be able to join a team.
I am going to create a table Teams with the following fields:
ID | Name | Description
and a table TeamMembership with the following fields:
UserID | TeamID | Role
As you can see, this table will link a member and a team, while leaving data specific to a user or team in their respective tables ONLY (successfully preventing redundant data). This sounds good, right?
Well, I don't want those two new tables in the same database as the SMF stuff, because it may get messy. Is it the easiest solution, though? Do you think the easiest solution is to just create my new tables within the same database, with the prefix cst for Custom? I have no idea how to link two databases so if it is too complicated maybe I should just do my cst solution.
I've edited this post and have an additional question.
Thank you for the answers. I have an additional question. Let's say that I wanted to extend new variables to the members, but again, wanted to avoid adding new fields into the SMF forum member table. What is the easiest way about going about this? Like, I want to create a table called UsersExtended and have fields such as:
-ID (this is NOT an auto-increment field, but the value of id_member from the SMF members table)
-Country
Is it easy to create a profile page with this structure and display any relevant data I want from the two tables, in a way, Linking the two so that they act as one big table?
They totally belong in the same database. Use one db and join the tables in your queries.
The only time you want to build a unique database for your application (other than for the application itself) is if you intend to create an API which will serve up that data to other projects in an unbiased manner. That is very common with Solr in which you can churn out blazing fast API's and generally don't belong mixed in with your current MySQL tables.
There is absolutely no harm in having the custom tables in the same database. You cannot define relations between 2 different databases in a relational database system.
If you're using MySQL have a look at this question's accepted answer. Remember you have to prefix your table with database name when querying across databases.
You may try this
SELECT *
from database1.table, database2.table
where database1.table.id=database2.table.id
You should only create two tables within the same database
**smf_members**
id_member | member_name | date_registered
**TeamMembership**
Team_ID | Name | Description | Role | id_member
If any user wants team membership the you can easily manipulate its record using join queries.
Don't know Simple Machines Forum - but I do know that most applications expect to be the only show in town.
I would create a new database = perhaps called "teams" with your own tables, and use NickCL's way of doing cross-database joins to join between the two applications.
You don't mention the specific database engine you're using (I assume it's MySQL), but logically, you can think of databases as namespaces - a way of keeping stuff that belongs together in the same logical place.
Ideally, "people"/"authentication" etc. should be in a separate database from the forums stuff - but as you're working with off-the-shelf code, you don't have that luxury.
In my experience, it's better not to mess with the databases of off-the-shelf software - when you want to upgrade, you have no idea what will happen to your own tables, regardless of their names....

Categories