Hard-coding URLs vs Nested Set vs Combo in Content System - mysql

I've been putting together a database to handle content produced for a site, however, thinking about the long-term, I'm unsure if I have the best system.
At present I'm using the routing method of passing everything via index.php which .htaccess routes as follows index.php?route=example/url (user sees http://www.domain.com/example/url)
At present the database is setup like below:
uid | title | content | category
--------------------------------------------------
/ | Home | aaa | 1
/example | Example | bbb | 2
/example/url | Example: URL | ccc | 2
Though I am not sure if this is the best approach, especially if I wanted to rename example to something - I'd have to rename each URL...
So I've also thought about the Nested Set method (such as http://www.phpclasses.org/package/2547-PHP-Manipulate-database-records-in-hierarchical-trees.html) though this would just show lots of different numbers in the database where I could access everything by it's node. Example below;
node | left | right | name
--------------------------
1 | 1 | 6 | Home
2 | 2 | 5 | Example
3 | 3 | 4 | URL
Then I could use the node as the uid? But I'm unsure how I could translate http://www.domain.com/example/url to the uid equalling 3...
I already do have a category column in my database at the moment, to categorise the content, though I could potentially alter this.
I'm basically looking for suggestions about how to proceed, because as the site gets more content it will be harder to change the setup - so I want to ideally get this right from day one.
Which of the two is better for scalability?
If the second, how to translate the URL to the node?
Could I somehow combine both so that the original database stores the uid as the node number, then do a join of some sort to make the uid be a url (as in 1) - then ]
^ I think I'd prefer this (the third), but unsure how to do in MySQL exactly, with some other benefits:
I could replace my category system with the parent node - which may be better
I could also then in theory store the node ID within a stats system, rather than a URL
If anyone can give some help/suggestions - I'd be grateful!

Well, if you use index.php?route=example/url, you could always do something like this:
$args = explode( '/', $_GET['route'] );
$args = filter_var_array( $_GET['route'], FILTER_SANITIZE_STRING );
Then your values of $args would be:
0 -> example
1 -> url
etc. You could then use these values to determine what template to load, and what content to grab from the database, or whatever else you're doing already.
HTH.

The nested set model probably is a good choice here. That'd result in a table layout like (id,left,right are the fields required by the nested set model, the others contain the respective content):
| id | left | right | uid | title | content | category |
More details on how to perform a particular query can be found here.
However I would not perform the look up on the database but a simple array cache:
new array('/' => array('content' => 'aaa', 'category' => 'bbbb'),
'/example/' => array(),
.....
);
This cache can be build up very easy (though expensive) and queried very easy.
On a side note: i suspect you're trying to model page content here. Maybe you should refactor you database structure then as this table would have two responsibilities (url->content mapping and content).

Related

How to create a page for database entries in a html page

At the moment I have this database:
|---------------------|------------------|
| Project | Task |
|---------------------|------------------|
| id | id |
|---------------------|------------------|
| project_name | task_name |
|---------------------|------------------|
| project_id(FK) |
|------------------|
The supplies table, has a list for (name of the item or task) (id) and the project it is assigned to via a foreign key.
I have a simple post HTML form that lets users fill it out, and that in turn updates the database
Now I'm looking to add a sort of "output" that lets me create hyperlinks (or small pages) to each project, so that users can have the option to delete the project/add new tasks into it and so on
The only part I'm struggling on is figuring out how to create a seperate type page, I have tried using this
while($row = mysqli_fetch_assos($result)) {
echo "<li>" . "<a href=clientportal.php?project_id={$row['id']}'>
{$row['name']}</a>" . "</li>";
}
But this creates a HTTP 500 error, which I assume is because I used post and not get in my form.
Is there another way to do what I am looking for? or should I go back to my form and change it to a get method
Ideally I'm looking for a simple list of current projects, with hyperlinks, that take me to a page where I can add some php/sql code to output a few simple SQL query options as mentioned, such as deleting the project, adding a new task etc.
Thank you!

UPDATE all empty array columns to be NULL

MySQL query is:
UPDATE buddy SET buddy_positions = CONCAT('| ',
(IF(buddy1_request = 'Yes', 'buddy1_main | ','')),
(IF(buddy2_request = 'Yes','buddy2_main | ','')),
(IF(buddy3_request = 'Yes','buddy3_main | ','')),
(IF(buddy4_request = 'Yes' NULL,'buddy4_main | ','')),
(IF(buddy5_request = 'Yes','buddy5_main | ','')))
My problem is that if buddy1_request = 'Yes' I want it to CONCAT the data in a separate cell (buddy1_main) plus some extra bits. I'm struggling to output the result from another column however, I can type it in manually but can't find a way to do this automatically.
EDIT
So my data looks like this:
|buddy1_request | buddy1_main | buddy2_request | buddy2_main |buddy_position|
|---------------|-------------|----------------|-------------|--------------|
|Yes |prop |no |NULL |(CONCAT HERE) |
So what I want to happen is that if buddy1_request says 'Yes' then it includes the contents of buddy1_main in the CONCAT for buddy_position and so on
In this example the output would simpley be "prop", however if buddy2_request said "Yes" it would have a value such as "winger" and the CONCAT would return "prop","winger"
My problem is that my current query returns the text "buddy1_main","buddy2_main"
I don't know how to reference the column and pull the value through in the CONCAT.
PS I don't see how this is bad design, it's a table where player adds a friend and if they click yes to playing with them that week it brings through their position as well into buddy1_main, I then need a way of outputting all the results into a table for clubs to view so they know that player also comes with X amount of people that can platy positions X,Y and Z.
However if player 2 is unavailable but player 4 is available it needs to ignore player 2's position. I hope that makes sense, there's a lot of reasons it's done this way and it's actually a very complex system when you drill down into it all. I've kept it this way so it's modular and not linear as a model so I can change aspects to it as needed without having a knock on effect. I'm not concerned about how memory hungry it is on the server at this stage.

MySQL table structure suggestions?

Hey i'm currently working on a database project and simply can't think of a good way to save my data. The data being saved changes depending on what is being saved.
My current not-so-good table is:
User-ID | XLoc | YLoc | ZLoc | Data-ID | Data (String)
The data column is currently being saved as a string (serialized depending on object being saved) then unserialized. I understand serialization is a dumb idea when it comes to a proper database, but i haven't a clue on how else i could've done this.
I was thinking about assigning "sub" tables depending on the Data-ID then joining all the tables together on a search but i feel that wont be very efficient.
So my idea would play out like:
User-ID | XLoc | YLoc | ZLoc | Data-ID | Data-Index
Data-Index | SomeObjectRelatingData | SomeObjectRelatingData
Once again i just don't know how i'd put this all together so any help at all would be EXTREMELY helpful and i'm sorry if i was vague.
Example Data:
Particle-Name(string) | Material (int)
Time(long) | MeshType (int)
This data is currently serialized like so: Time:MeshType in string format. Once the data is retrieved from the database it's deserialized then changed back into it's formal type;
All the data needs to be accessed easily and they all share the User-ID, XLoc, YLoc, ZLoc.

Creating SQL Table layout for dynamic document

I apologize if this question is vague, but I'll try to be as clear as possible. I've been given a task where I'm to take a text file, store its content in SQL Server 2008, and automate the creation of a form letter given certain inputs. I've been able to break it into the following generic structure (pay no attention to the content, it's just generic text, but the situational break-down is similar):
Welcome [User],
[if #purchase = true, add this paragraph]
Thank you for purchasing the [device / subscription / subscription and device]
from this business on [date].
[#purchase = true and #return = true, add this paragraph]
I'm sorry you returned it!
...
Signed,
[Author]
[Author Image]
Assuming I'm already able to bring in all the necessary variables (user, purchase, return, date, device or device and subscription or subscription only), how should I go about storing the letter pieces in SQL? would it be considered fine to have a structure like the following:
+-------+-----------------+----------+--------+
| Order | Text | purchase | return |
+-------+-----------------+----------+--------+
| 1 | (1st paragraph) | TRUE | null |
| 2 | (2nd paragraph) | TRUE | FALSE |
+-------+-----------------+----------+--------+
Where I store the contents of the first paragraph as:
Thank you for purchasing the [device / subscription / subscription and device]
from this business on [date].
And then write a stored procedure to piece it together based on the Boolean columns, and find/Replace the bracketed bits with input variables to output the entire letter as a string? It doesn't seem like it would be able to handle much variability, to be honest. Maybe breaking down the document into paragraph and sentence tables?
My ultimate goal would be to output this to either a report I create or, perhaps more ideally, to a Word document (though this is probably a whole different bit of research). Am I way off base here? Any insight is helpful.
you can use replace in select statment
for example
SELECT replace(replace(Text, 'device', #deviceVaribale), 'subscription', #subscriptionVaribale) FROM Order

Is it more performant to have rows or columns in sql?

If I have to save many strings that are related and that may be dividied in different languages: What's the best way to do it?
I think I have the following options. Option 1 and 3 is the most clear solution to me. They have more columns, but result in fewer rows.
Option 2 and 4 are the most flexible ones (I could dynamically add new string_x without changing the database). They have only three columns but they will result in many rows.
Option 5 would result in many tables.
Option 1:
id | string_1 | string_2 | string_3 | string_4 | ... | string_n | lang
Option 2 *(where name would be string_1 or string_2 etc.)*
id | name | lang
Option 3
id | string_1 | string_2 | string_3 | string_4 | ... | string_n
id | lang | stringid
Option 4
id | lang | stringid
id | name
Option 5
id | string_1 | lang
id | string_2 | lang
id | ... |lang
I'm using it to store precached html values for multiple views (one line view, two lines, long description, etc.), if this is of interest.
Option 1 and 3 are not recommended, as you end up with the language (which is data) in the field name. You have to change the database design if you want to add another language.
Option 5 is not recommended, as you end up with the string identifider (which is data) in the table name. You have to change the database design if you want to add another string.
Option 2 or 4 would work fine. Option 4 is more normalised, as you don't have duplicate string names, but option 2 might be easier to work with if you enter values directly into the table view.
Having many rows in a table is not a problem, that's what the database system is built for.
Although I've not had to specifically deal with multi-language interfaces, and if that is all its purpose is, is a translation, I would to option 1, but swapped, something like
id English French German Spanish, etc...
So you would basically have a master column (such as English) as a "primary" word that is always populated, then as available, the other language columns get filled in. This way, you can keep adding as many "words" as you need, and if they get populated across all the different languages, so be it... If not, you still have a "primary" value that could be used.
It depends on a lot of other things. First of all, how many strings could there be? How many languages could there be? To simplify things, let's say if either of those numbers are greater than 5, then options 1 and 3 are infeasible.
Before I go any further, you should definitely look into implementing multi-language functionality outside of the database. In PHP you can use Gettext and put your translation data in flat files. This is a better idea for multiple reasons, the main ones being performance and ease of use with external translators.
If you absolutely must do this in a database then you should use a table structure similar to this:
id | string | language
An example entry would be:
welcome_message | Hello, World! | english
Which I think you've described in Option 2. To clarify, depending on the amount of different languages and different strings, you should use a single table with a fixed number of fields.
If you support only a few languages, you might also consider a schema in which each language is its own column:
ID EN ES FR Etc...
This is less normalized than your option 4, but it is very easy to work with. We have built our database translations like this. As we develop code, we create string resources fill in the English text. Later, a translator fills in the strings of their language.