Alter MediaWiki's user table - mediawiki

How can I change the default MySQL table "user" , that's used to store all members?

is it more of a database question? in mysql you could issue command, for example:
ALTER TABLE user ADD COLUMN user_birthday DATE;
check the actual name of user table. MW uses table prefix option which may not be empty.
The actual statement will depend on what column you want to add of course.
However, for the better portability of your wiki (e.g. easier upgrade) you might want to create a new table instead for the user profile that would have user_id as FOREIGN_KEY
Also there is a field user_options which stores name=value pairs of extra data. - you can make use of that if you don't care about searching your DB against the new "field".

Do not.
If you need to alter the user table (and related) server-side, use the appropriate maintenance script: createAndPromote.php is among the most used, there are others for specific functions.
You didn't specify your use case, but chances are that you're going to break MediaWiki in unexpected ways if you try to manually alter the table.

Here is some information about the "user" table.

Related

Table Rows or Columns

I have a project which requires me to setup custom privileges, divided in three categories "Admin, Manager, User"
My regular approach is to distribute Privileges in one table as headers, then add a raw for each category with 0 or 1 to activate or deactivate the privilege for a group like follows:
id|name|can_do_this|can_do_that
1|admin|1|1
2|manager|1|0
3|user|0|0
however my professor requested that each privilege to be added separately per user no per group like follows:
id|user_id|privilege|active
1,1,can_do_this,1
2,1,can_do_that,1
3,2,can_do_this,1
4,2,can_do_that,0
my question, for the sake of my sanity.. which is more efficient? his point is that IF we needed to add a new privilege we won't need to ALTER the table to add a new column.
hope this question makes sense.
To me, this is a very simple data modeling issue. You have two "entities" in your data model:
users
privileges
This suggests that each one should have its own table.
Because this is a many-to-many relationship (many users can have a given privilege, one user can have many privileges), a third table is normally used for expressing the relationship; this is often called a "junction table" or "association table".
Your professor gives one very good reason for expressing the values in rows rather than columns: The ability to add new privileges.
I can add a few more:
The userPrivileges table can have a createdOn column so you know when the privilege took effect.
The userPrivileges can have a createdBy column, so you know who granted the privilege.
The userPrivileges table can have a suspended column, so you can temporarily suspend privileges.
I would suggest you the second one, because like that as your teacher says you don't need to Alter the table. Altering the table would mean adding a new 1 or 0 for each member in your table (you could use a default value but you will still need to change the values for those users that need the privilege).
The way your teachers says you could have another table with all the privileges, and use a foreign key.
That way you could add a new privilege and asign it to the users they need it with a default value of "1", and if you need to revoke the privilege change it for a "0". No innecesari rows will be added for default, that in small tables is not a problem but for bigger ones it is.
id |user_id |privilege |active
1 1 can_do_this 1
2 1 can_do_that 1
3 2 can_do_this 1
4 2 can_do_that 0
As per my experience, If you don't want to add the extra column every time whenever a new privilege required to be updated in apps. Then go with second option.
Benefit:
Option-1: There will be no redundant data for group and that can be managed easily as you can apply the unique constraint on the group name and hence it will not requires the insert every time.
Option-2: You don't need to add the alter the table you can simply verify does new permission is already there or not, if not then simply add a new insert or update the existing permission.
Dis-advantage:
Option-1: You need to alter the table every time whenever new permission comes in.
Option-2: Whenever you want to add the new permission for a group first you have to identify that the records already exists or not, then you have to insert into table. And while validating the is also a bit of complex compare to the first option.
So, both has its advantage and disadvantages. If you think from data redundant perspective then go with option-1, else go with option-2.
I would prefer to go with option-1 as per my knowledge, and what I will do I just maintain a extra table which identify the permission and physical column between them, and I will make it generic.
ThatsAll!!!

Add new columns without using Alter

Is it possible to add new columns to an existing table without using alter statement?
Other people are answering unequivocally "no, it is not possible." This is the answer to your literal question. But I'm wondering why you ask the question.
One of the biggest pain points of MySQL is that using ALTER TABLE locks the table while you're making a change like adding a column, and the more data in your table, the longer this lasts while it restructures the table. I'm guessing this is the issue you have, and you're trying to get an alternative that doesn't block access to the table while you're adding a new column.
(In the future, it would help folks give you the best answers if you explain more about what you're trying to do.)
The answer to this question is yes, there is a solution: pt-online-schema-change is a free tool that accomplishes this.
You use it just like you would use ALTER TABLE, but you use it at the command-line instead of in an SQL query.
pt-online-schema-change --alter "ADD COLUMN c1 INT" D=sakila,t=actor
In this example, the database name is sakila and the table name is actor. The script does a lot of work behind the scenes:
Create a table like the original table, but empty of rows
ALTER TABLE to add the column or whatever other alteration you told it. You can do anything you would normally do with ALTER TABLE. In fact, it's doing ALTER TABLE for you, against the empty copy table.
Copy rows from the original table to the new table in the background.
Create triggers to capture any changes made to the original table while it's gradually copying the bulk of the data.
Swap the names of the new table (with the extra column) and the original table, once all data has been copied.
Drop the original table.
This has a few caveats, like the original table must have a primary key, and must not have existing triggers.
It tends to take longer than doing a traditional ALTER TABLE, but since it's not blocking access to the original table, it's still more convenient.
Does this help?
Is it possible to add new columns to an existing table without using the alter statement?
No.
Is it possible to add new columns to an existing table without using alter statement?
I don't think it's impossible.
However I'm not sure what you want to do.
lets say you have a table
select * from Store
and you want just export the data or perhaps you want to do something with that data like a selection. but you don't want to STORE the data in your Database
you can just fill a value and give it a name
select
'Test' as name,
*
from Store
this will populate your column with the value your entered.
data results

MySQL Id columns

I am working on a project that is an upgrade of an existing system.
The existing DB structure must be kept intact as there is a system reading the same DB that will be used ontop of the new system.
I am building a new CMS / Management system using a PHP framework that expects so see all DB table autoincrement ID field named simply "id" - I do not want to modify the PHP deal with anything other that "id" as this field name - trust me it will be a massive task.
The existing DB has non standard Autoincrement ID field naming, eg:
"iBmsId" -shcema: i=INT Bms = the name of the table, Id = ID....
Is there anything I can do to the DB itself to make a duplicate of the "iBmsId" column, to create a matched column called simply "id" that has the corresponding INT values? This way my new system will function as expected without having to do a serious re-write, and at the same time still have the existing system able to communicate with the DB?
In this situation you can just use VIEW :)
http://dev.mysql.com/doc/refman/5.0/en/create-view.html
View in dbms is like a virtual table (unless it's materialized). Views add a new abstraction layer which can support independency between how you use db and how it's implemented. It can also increase security for example by hiding some fields or making view readonly.
Notice: In order to add view transparently you can rename origin table and create the View with origin table name. This let's you avoid modifications in existing code.
You can read here how to create updatable and insertable view (which can behave as normal table).
If only one system at a time is modifying the value, then you can use a view:
create view v_table as
select t.*, iBMid as id
from table t;
Presumably, an auto-incremented value is not going to be updated, so this should be safe. However, keep in mind that:
To be more specific, a view is not updatable if it contains any of the following:
. . .
Multiple references to any column of a base table.
This could affect other columns that you might want to treat the same way.

MySQL change a column to unique

I have a database table that saved users profile information.
Sometimes when users register, they get duplicated with an extra column with same records, sometimes not.
So, I wonder if I put Unique on the column Email to make sure the user don't dup when register.
I think it should be something like this:
ALTER TABLE users ADD UNIQUE idx_row_unique(email);
But in case the Unique give error, how do I undo it?
Just scare that after I change it, I don't know how to undo it.
If there are duplicate emails, the alter table should fail. So you're safe with that!
I'd export the table structure and data first. That way if you need to put it back, you have the SQL right there.

MySql Soft delete

I have an existing application (with MySQL DB).
I just got a new requirement where I need to delete some records from one of main entity. I dont want to apply hard delete here as its risky for whole application. If I use soft delete I have to add another field is_deleted and because of that i have to update all my queries (like where is_deleted = '0').
Please let me know if there is any smarter way to handle this situation. I have to make changes in half of the queries if I introduce a new flag to handle deletes.
Your application can run without any changes. MySQL is ANSI-SPARC Architecture compliant . With external schema you achieve codd's rule 9 "Logical data independence":
Changes to the logical level (tables, columns, rows, and so on) must
not require a change to an application based on the structure. Logical
data independence is more difficult to achieve than physical data
independence.
You can rename your tables and create views with original table names. A sample:
Let's supose a table named my_data:
REMAME TABLE my_data TO my_data_flagged
ALTER TABLE my_data_flagged
ADD COLUMN is_deleted boolean NOT NULL default 0;
CREATE VIEW my_data AS
SELECT *
FROM my_data_flagged
WHERE is_deleted = '0'
Another way is create a trigger and make a copy of erased rows in independent table.
Four suggestions:
Instead of using a bit called is_deleted, use a dateTime called something like deleted_Date... have this value be NULL if it is still active, and be a timestamp for the deletion date otherwise. This way you also know when a particular record was deleted.
Instead of updating half of your queries to exclude deleted records, create a view that does this filtering, and then update your queries to use this view instead of applying the filtering everywhere.
If the soft deleted records are involved in any type of relationships, you may have to create triggers to ensure that active records can't have a parent that is flagged as deleted.
Think ahead to how you want to eventually hard-delete these soft-deleted records, and make sure that you have the appropriate integrity checks in place before performing the hard-delete.