Best way to modify site to allow anonymous comments - php

Now I have one table "comments" with 'user_id' column as foreign key. This column have a constraint - ON UPDATE CASCADE, ON DELETE CASCADE.
First (bad) way is to remove constraints for 'user_id' column. In that case we loosing connection with 'users' table, but all code stay same.
Second (also not good) way is to create one more table 'anonymous_comments'. New model, new observers, new chapter in admin panel, need to modify code in many places... many work & doubles.
Any better ideas?

If you don't want (or can't for some reason) to do any DB and code modifications, you could create a dummy user 'anonymous' and use it's user_id for anonymous comments.

Related

differences between adding Foreign constraint and without on mysql table

At past, I was used to make a table relationship programmatically, which is quite handy since you don't need to make FK constraint to each table which have relation.
But, I wonder what is the differences or the advantages of giving a FK constraint to tables that have relation, instead of just creating an attribute and retrieve them programmatically (calls the tables where field = another table PK).
Just some information, I work on php independent MVC framework without any dependency to eloquent or something else.
Hope someone give me some short lesson on this :D Thank you and have a nice day!
There are certain principles that you should follow while coding and development, I can say that there is no issue whether or not you create a foreign key constraint to a table that has relation or not but you know that won't restrict the column to have only those values that are being referenced by it. So basically it is not a good DB Schema and may lead to inconsistencies. For example deleting a parent table's row you will have to manually delete the child table's row on the other hand if you have a foreign key constraint that to onDelete = cascade, your database will automatically take care of everything and there won't any inconsistencies.

How Do I get RedBeanPHP to work with a MySQL Table with ID primary key (uppercase only)? [duplicate]

If you use RedBean ORM, do you need to add a primary key named "id" to every table in your database?
In my db I have a few tables that have primary keys pairs of 2 or 3 fields, or primary keys with other names than "id" (yes, I could change the name to "id", but it wouldn't really reflect the reality, because they are not IDs)
Example:
table1 - stores posts:
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
title TEXT,
content TEXT,
table2 - stores meta for posts:
post INTEGER DEFAULT 0, # <- references "id" from "posts"
name TEXT,
value TEXT,
PRIMARY KEY(name, post),
CONSTRAINT posts_meta FOREIGN KEY(post)
REFERENCES posts(id) ON DELETE CASCADE ON UPDATE RESTRICT
Would RedBean work with this kind of db structure?
Unfortunately, with how your current table structure is, you couldn't use RedBean. Every table needs to have an auto-increment primary key. A slight downfall, as it makes integration into an already existing product more difficult.
A couple of threads that failed to use RedBean due to this constraint, with responses from the author, Gabor De Mooij:
http://groups.google.com/group/redbeanorm/browse_thread/thread/6d5582275326744f?pli=1
http://groups.google.com/group/redbeanorm/browse_thread/thread/4fa7b29b453dcdb8
RedBean does NOT require the primary key field to be named simply "id", however. You can format the name of the primary key column to your liking by using the formatBeanID() method, as seen in the example below, which prefixes the table name to the "id" conditionally. eg) table users would have the primary key be users_id. Using that formatting, you can get as detailed with the id name as needed.
http://redbeanphp.com/community/wiki/index.php/Prefixes
Hopefully this restraint will be lifted in the future, since it really does hamper the integration into existing products.
EDIT: As an alternative ORM, I've heard well of Doctrine: http://www.doctrine-project.org/. I haven't personally used it, but it seems to be the standard for many working with PHP.
EDIT 2: Thanks and credit to Jason for bringing to attention a new method for integrating RedBean into an existing project where your database might not be set up for it. I wanted to update my answer as well in case people still reference it with this problem. Gabor suggested making views that map to the tables, where you can set up the view to have the proper structure required for RedBean. I have not personally tested this, but it has gotten positive feedback from some users. It adds some extra overhead and maintenance when altering tables, but seems to be the best and most complete answer to this issue to date.
http://www.redbeanphp.com/faq#beanformatter
The accepted answer is not strictly true... You can use the existing table structure - but you would need to implement a VIEW on top of each of the tables that allow you to rename the PKEY column to be 'id'... See this email from Gabor - the creator of RedBeanPHP:
https://groups.google.com/forum/#!searchin/redbeanorm/view/redbeanorm/wXUeT4Tj2uU/3AngnmVwZdYJ

Change id from autoincrement to char 36 in CakePHP

I have web application built on CakePHP 1.2.11. and mysql database. In this application I have two tables, namely, users and actions. Users hasMany actions and the user_id (id in users tables) is the foreign key in actions table. The id field is autoincrement integer.
CakePHP documentation said that setting the id field to be Char(36) will make CakePHP able to generate Unique string for each record to be the id.
My application is running and I don't want to loss the data records that my application already has. I need to know if it is safely possible to migrate from autoincrement integer id to char(36) keeping in mind the related table?
In other word, How could I change integer value to the unique string id that cakephp do? Is there any rules? If there any tool automate this kind of migration, I will be appreciated to know it.
Yes, simply alter the table to use a varchar. An INT column can be translated into a char, so you won't lose the original IDs (you will end up with a mix of both old regular ints and new uuids). You will need to make sure the change is also made to any foreign keys on any other tables that will need to store VARCHAR(36) as well.
Then make sure to push the new code live immediately otherwise the new records will not be able to be created, because a varchar field can't be auto-increment.
Lastly, immediately after pushing the new code, clear your model cache so Cake doesn't still think it's an INT.
Are you sure you want to switch?
Honestly, unless you have a really good reason to change to UUIDs (CHAR(36)), then I would recommend just staying with auto-incrementing IDs. There are plenty of people that tout the benefits of each, but it boils down to auto-incrementing IDs can be faster, and unless you have multiple databases where you're worried about overlapping data, auto-ids are just fine. (And it's not a simple "switch")
Not crazy-simple:
If you still are sure you want to switch to UUIDs, there is no automated process, but be careful - it's not just about switching the field types and voila - you'll have to create a script or something to update the id fields as well as all the associated fields (ie 'user_id' in the 'actions' table won't be updated..etc etc).
If so, here's how:
So - create a duplicate of your database (or tables) as back-up. You'll then probably want to rename the 'id' field to 'autoid', create another id field CHAR(36), run a script to populate all the UUIDs, then another script that populates the associated ids (ie 'user_id' in the 'actions' table) with the corresponding UUID.
CakePHP code that generates UUIDs:
Here's the link to creating a UUID in CakePHP 1.2: http://book.cakephp.org/1.2/en/view/826/uuid

Do you need to set foreign keys in MySQL?

Let's say you have got two tables like the following in a MySQL database:
TABLE people:
primary key: PERSON_ID,
NAME,
SURNAME, etc.
TABLE addresses:
primary key: ADDRESS_ID,
foreign key: PERSON_ID,
addressLine1, etc.
If you manage the creation of rows (in both table) and the retrieving of data trough PHP do you still need to create a physical relationship in the database? If yes, why?
Yes, one concrete reason is to have faster retrieving of rows if you want to join tables. Creating a foreign key constraint automatically creates a an index on the column.
So table address' schema should look like this, (assuming People's table primary key is PERSON_ID)
CREATE TABLE Address
(
Address_ID INT,
Person_ID INT,
......,
CONSTRAINT tb_pk PRIMARY KEY (Address_ID),
CONTRRAINT tb_fk FOREIGN KEY (Person_ID)
REFERENCES People(Person_ID)
)
Strictly speaking: You don't need to use FK's. careful indexing and well written query's might seem to be sufficient. However FK's and certainly FK constraints are very useful when it comes to securing data consistency (avoiding orphaned data, for example)
Suppose you wrote your application, everything is tested and it works like a charm. Great, but who's to say that you'll be around every time something has to be changed? Are you going to maintain the code by yourself or is it likely that someone else might end up doing a quick fix/tweak or implement another feature down the road? In reality, you're never going to be the only one writing and maintaining the code, and even if you are the only one maintaining the code, you're almost certainly going to encounter bugs as time passes...Foreign keys inform both your co-workers and you that data from tbl1 depends on the data from tbl2 and vice-versa. Just like comments, this makes the application easier to maintain.
Bugs are easier to detect: creating a method deleting a record from tbl1, but forgetting to update tbl2 to reflect the changes made to the first tbl. When this happens, the data is corrupted, but the query that caused this won't result in errors: the SQL is syntactically correct and the action it performs is the desired action. These kind of bugs could remain hidden for quite some time, and by the time this is spotted, god knows how much data has been corrupted...
Lastly, and this is an argument that is used all too often, what if the connection to the DB is lost mid-way through a series of update/delete query's? FK Constraints enable you to cascade certain actions. I haven't actually seen this happen, but I know of anybody who doesn't write code to protect against just such a scenarioDeleting or updating several relational records, but mid-way, the connection with the DB gets cut off for some reason. You might have edited tbl2, but the connection was lost before the query to tbl1 was sent. Again, we end up with corrupted data. FK CASCADE's are very useful here. Delete from tbl1, and set an ON DELETE CASCADE rule, so that you can rest assured that the related records are deleted from tbl2. In the same situation, ON DELETE RESTRICT, can be a fairly useful rule, too.
Note that FK's aren't the ultimate answer to life, the universe and everything (that's 42 - as we all know), but they are a vital part of true relational database-designs.
Referential integrity is an article that you should read and comprehend.
there are two ways
-first one is to handle all the things on coding end manage the things on deleting or updating a record
but when you use foreign key you are enforcing the relation and Db don't allow you to delete records with foreign key constraint especially when you don't want to delete the records related to it there is some situations accrue where you need to do this kind of tasks.
-Second way is to manage things on the Db side. If you have 1-to-many or many-to-many relations in database, foreign keys will be very useful. Also they have some good actions - RESTRICT, CASCADE, SET NULL, NO ACTION those can do some work for you

Cascade a value in a table

Lets say I have two tables, 'a' and 'b'. The relationship of 'a' to 'b' is one to many. Lets both tables have the field status. This field has the values 'active' and 'inactive'. If I set the field status to 'inactive', does MySQL have a way to cascade this down to all tables tied to the row I changed the status value for? Or would this have to be done at the program level?
Let me know if this isn't clear.
You could use a trigger on the parent table that updates all children as necessary. Otherwise you'll have to handle it at the same level of your application where you update the parent row.
I've never tried this, and I'm not sure if I would recommend it, but if you add the status column to your foreign key (so you have two columns: the primary key of table 'a' and status) and then use on update cascade that might work as well.

Categories