This topic is locked

Add Fields to an Existing MySQL Table

8/3/2024 11:22:55 AM
PHPRunner General questions
A
alfonso authorDevClub member

I would like to know if it is possible to create a form in which fields are added to an existing table. And then, from another section, to be able to add records to said table with the created fields.
For example, I have a table called clients. It has some fields: IDE, name, address, city. So I want to create an option from the project in which it is possible to add new fields. For example, a field called preferences, which is of type varchar, of size 200.
And then in another option of the menu, that records can be added in which that newly created field appears

C
cristi 8/4/2024

You can do that with SQL but it is uncommon: for example provided that all clients have an primary key - client.id - you can create a new table let's say client_preferences and store in ENUM fields all these custom fields and retrive them later based on client.id - I hope this is enough to get you started. You also need to create another table for client_attributes that will tell you what kind of field the client added based on the client.id.
But again this is uncommon and it is not best serverd by a relational database like MySQL - the way it is done is by using a document database (NoSQL) with JSON, BSON or XML format. The main advantage from my point of view is that document databses have dynamic schema - it can be altered on the fly. Consider something like MongoDB or CouchDB for this.
You can use MongoDB for example with MySQL - I use it for geospatial data (query against it) and caching while MySQL is the primary database for storing data and it works wonders.

There is also the "ugly" solution of adding a lot of custom fields to the table and made them available to users per request and run a query to insert those custom fields - not that elegant and modern.

Here is an article for you: article

An anther one: article

Sergey Kornilov admin 8/4/2024

Adding a column to the database table is not difficult but not very useful. You simply need to execute a SQL query like this:

ALTER TABLE Customers ADD Email varchar(255);

But the big question is - what are you going to do with this new field. PHPRunner is not aware of this new column and cannot do anything about it. If you need to work with database structure that can change, you need to take a different approach. Check Forms template for instance, that does something very similar:
https://xlinesoft.com/forms

M
MikeT 8/4/2024

I would avoid this as much as possible, but if there's the need for a dynamic structure it is usually done with a field that stores JSON. Xlinesoft does this e.g. in the documents manager template to store meta data about files. You can then parse out the relevant data in "view as".
In newer versions of mysql/mariadb and especially postgres there are even native JSON functions and types, which can be very useful in such scenarios.

C
Chris Whitehead 8/4/2024

As it's been said, JSON is ideal for this, if your DB doesn't support JSON, what about using another table for the extra fields and access them as a child table to your main clients table which you can display on the edit page.

I have an older DB so I can't use JSON on that one , I also have different types of users, some need extra fields and others don't, I tried to explain it in English but it sounded like I was just waffling, so I ran my ramblings through chatGPT so it's sounds a bit more sensible.

Problem
You need to handle dynamic extra fields for different types of users in a database that does not support JSON.

Solution
Use two separate tables to manage extra fields dynamically:

client_details Table
This table stores extra fields as key-value pairs linked to each client.

CREATE TABLE `client_details` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`client_id` INT(11) NOT NULL, -- Reference to client
`field_name` VARBINARY(255) NOT NULL, -- Name of extra field
`field_value` VARBINARY(255) NOT NULL, -- Value of extra field
PRIMARY KEY (`id`),
UNIQUE INDEX `client_id_field_name` (`client_id`, `field_name`)
)
ENGINE=MyISAM;

client_id: Links to the main client record.
field_name/field_value: Stores additional data for each client.
client_detail_fields Table
This table defines available extra fields and their defaults. You can use this table for the dropdown in field_name

CREATE TABLE `client_detail_fields` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`details` VARCHAR(50) NULL, -- Field name
`default_value` VARCHAR(50) NULL, -- Default value
`client_group_id` INT(11) NULL DEFAULT '0', -- Applicable client group
PRIMARY KEY (`id`)
)
ENGINE=MyISAM;

details: Name of the extra field.
default_value: Default value if any.
client_group_id: Specifies applicable user groups.

How It Works
Dynamic Fields: client_details allows any number of custom fields per client.
Field Configuration: client_detail_fields manages field options and defaults.
Flexible Design: Supports different user needs without changing the main client table.
This approach keeps your database structure flexible and efficient for handling dynamic data.

M
MikeT 8/4/2024

Just as a clarification: the db engine itself doesn't necessarily need to support JSON natively, you can just use a text fields to store the JSON blob and add code in the field display / store events to parse/encode back and forth. As said, an example can be found in the documents manager template.
If the database engine supports JSON it just gives you some of this for free, and can also help e.g. to produce JSON as query results which can be handy if you're e.g. handling out JSON via your own REST api.
As a side note: in the most recent postgres version, I think, you can basically do everything for a REST API in the db itself(!).

C
Chris Whitehead 8/5/2024

@MikeT You're right, it doesn't need to support the JSON search functions, you can just json_encode it and drop it in. I was thinking that @alfonso wanted to add a field and then make it available in the other clients.

A
alfonso authorDevClub member 8/5/2024

Thanks for the clarifications.
It would really be for a single user. He wants to make a form for people to sign up for activities. But each activity may need additional fields. That's the reason and the idea: not having to manually create those fields, then access the project made with phprunner to use those new fields in the Add of the table.

C
cristi 8/5/2024

What you want is not something trivial than can be shown in a couple of lines of code...
It's not something complicated and you have a lot of suggestions from here on where to start.
And yes, today I see a lot of users (in what we do for others) that want to have more control of applications: to be able to generate their own fields, to be able to generate customized reports based on what they want to be there.
As a suggestion I think that this example: generating custom fields - that was requested also in the past - could be a great example for the blog that was not updated from january....I know that v.11 takes a lot of time and there is the devclub but some things can be shown in the blog to attract other people as a showcase of what PHPRunner can do - maybe when there is a little time...

mbintex 8/5/2024

One should not forget that nowadays our products - if we offer our software as Saas - will be compared to solutions like Airtable, Smartsuite and so forth. And there users can add and alter fields to there likings. This is getting a "standard" in my eyes and not something too sophisticated.

So a decent update to v11 could bring the ability for more flexibility in this respect.

Same with the ability to online change views and print layouts to the likings of the user.

M
MikeT 8/6/2024

expanding on @mbintex remarks and following the discussion here: What I personally miss the most is a concept of "unbound fields", maybe people with experience in other RAD tools like Access know what I mean.
In other words: UI-fields that basically offer almost the same control via event hooks etc. as real db fields.
There are workarounds, I know, you can do something like that with virtual fields in queries or changing UI-template code, code snipptes etc., but it would be great if it would be supported a bit more "natively".