When I update from PHP code my DB table based on any column name(id, username, whatever) - everything goes well. But if I try to update it based on an IP - it fails.
I store the IP as varchar(39) and using MySQL.
Perhaps someone here would know why is it can't access(update) it based on IP?
Thanks
Update:
The schema of the table is very simple, it contains:
|id|userid|username|ip|date
The code is coming from class to class... I tried to use it as best as I could with OOP with lots of helpers. But the main point is that it works great, but not with the IPs...
By googling I found out ip2long function, so it's probably something related to the issue.
Update 2:
+----------+-------------+------+-----+
| Field | Type | Null | Key |
+----------+-------------+------+-----+
| id | int(11) | NO | PRI |
| userid | int(11) | NO | |
| username | varchar(20) | NO | |
| ip | varchar(39) | NO | |
| date | datetime | NO | |
+----------+-------------+------+-----+-
Made it by hand :) No idea what should be the datetime exactly
Related
I'm creating an application using PHP (Codeigniter/MySQL) and within the application are organisations.
Each organisation can have multiple locations, regions, departments, etc (I'm calling these areas)
Each area has an administrator, and sometimes I will need to escalate things to a higher area.
I've currently got all the data in 1 table, and I am using a parent_area_id and area_level to determine the parents,children etc.
But I think this is very inefficient, and I've been pointed towards closure loops, which I have no knowledge of.
Here the database table, is this ok, will it be efficient or is there a better way to do it?
+----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+----------------+
| area_id | int(12) | NO | PRI | NULL | auto_increment |
| area_title | varchar(40) | NO | | NULL | |
| area_name | varchar(40) | NO | | NULL | |
| address1 | varchar(40) | YES | | NULL | |
| address2 | varchar(40) | YES | | NULL | |
| address3 | varchar(40) | YES | | NULL | |
| town | varchar(20) | YES | | NULL | |
| county | varchar(20) | YES | | NULL | |
| post_code | varchar(10) | YES | | NULL | |
| has_ra | varchar(1) | YES | | 0 | |
| org_id | int(12) | NO | MUL | NULL | |
| parent_area_id | int(8) | YES | | NULL | |
| area_level | int(1) | YES | | NULL | |
+----------------+-------------+------+-----+---------+----------------+
EDIT:
(better explanation of how this is being used)
1) Areas relate to customers of the business only.
2) The areas are different area(region,location,department) that a customer might have. (South region, Oxford Office, Accounts Dept).
3) Each area may have many employees allocated.
SO
If I had a regional administrator for example, they might have the following areas under them: e.g:
South Region
Oxford office
Sales Department
Accounts Department
London Office
Marketing
Planning
SO
If I wanted to get the user_id's of all employees under the regional administrator, using the above database structure, i would need to:
1) Query the db to get all area_id's that have a parent_area_id of the regional administrator.
2) Loop through each returned area_id, and query the db and get all area_id's that have a parent_area_id of the returned area_id
3) Continue looping through returned area_id's until we get to the bottom level
4) Query the db to get all user_id's that have an area_id of all above returned records
SO
That doesn't seem very efficient, and needs multiple SQL queries and programming loops to get a list of users associated with a regional manager.
If thats the most efficient way to do it then fine I just don't seem convinced, and im sure there must be an easier way?
There's no serious problem here if you're dealing with a situation where you're escalating one level at a time. I've got no idea how "closure loops" would factor in here, that's programming related, not a database schema concern, and is largely a matter of personal preference.
So long as you don't violate the Zero, One or Infinity Rule of design, you should be okay. Your multiple address fields here skirt the line, that might be better represented as a single field that accepts multiple lines of text, but that is also how a lot of databases traditionally represent arbitrary street addresses.
I'm trying to make a small logging table on my database.
Users
+----+------+
| id | name |
+----+------+
| 1 | FOO |
| 2 | BAR |
| 3 | LOS |
+----+------+
Log_Users
+-------------+-------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| old_id | int(11) | YES | | NULL | |
| old_name | varchar(100) | YES | | NULL | |
| new_id | int(11) | YES | | NULL | |
| new_name | varchar(100) | YES | | NULL | |
| action_type | enum('C','U','D') | YES | | NULL | |
| time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| doers | int(11) | YES | | NULL | |
+-------------+-------------------+------+-----+-------------------+-----------------------------+
I have a small application created using PHP to save user's id into session. How do i send this user's id value (on PHP's session) to a trigger of one of the tables to log their activities, like deleting another users or updating them? I've tried to use a trigger on log table to do all of the things, something like this.
CREATE TRIGGER userTrigger BEFORE INSERT ON Log_Users FOR EACH ROW
BEGIN
IF(new.action_type = 'C') THEN
INSERT INTO Users(id, name) VALUE(new.new_id, new.new_name);
ELSEIF(new.action_type = 'U') THEN
UPDATE Users SET id = new.new_id, name = new.new_name WHERE id = new.old_id;
ELSEIF(new.action_type = 'D') THEN
SET new.old_name = (SELECT name FROM Users WHERE id = new.old_id);
DELETE FROM Users WHERE id = new.old_id;
END IF;
END~
But, I'm struggling on the problem when users updating multiple records on the same column. At the end, what is and how to make an optimal activities logging using PHP and MySQL and how to do it? I have no solution for this problem for now. Thank you.
I've never done this using triggers so I can't help you with that sadly. How I usually do this:
Your users should NEVER have direct access to mysql or phpmyadmin, they should create, edit, delete and anything else using a PHP script you provide. This way you have total control over what your users can and can't do, and you narrow a lot the posible actions performed, so creating logs of them is much easier. For example:
You have a php scrip that users use to do some stuff and insert a new row, right after that you do a insert on the log table recording this last action.
I am working on a project and I ended up with the table below:
+---------------+--------------+------+-----+--------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+--------------------+-------+
| id | int(11) | NO | MUL | NULL | A_I |
| user _id | int(11) | NO | | NULL | |
| info | varchar(255) | NO | | NULL | |
| country | tinyint(3) | NO | | NULL | |
| date_added | timestamp | NO | | 0000-00-00 00:00:00| |
+---------------+--------------+------+-----+--------------------+-------+
Because I wanted to avoid storing countries as varchar all the time I thought I should use number IDs instead. My question is, would it be better to store the country IDs in a table where I would give a name to each one of them or do that in a php file? Countries won't change or anything. It will be a list of around 100 countries.
Thanks!
Use a seperate country table.
countries table
---------------
id
name
Then you can relate to the country ID in your table. That way you make sure only countries from your list are added and you don't need to store strings everywhere and you can easily change country names or addnew ones.
I'm using generic Sphinx with Python (though I tested this against PHP as well and got the same problem). I have a table where I have several fields I want to be able to search in sphinx against but it seems like only some of the fields get indexed.
Here's my source (dbconfig just has the connection information):
source bill_src : dbconfig
{
sql_query = \
SELECT id,title,official_title,summary,state,chamber,UNIX_TIMESTAMP(last_action) AS bill_date FROM bill
sql_attr_timestamp = bill_date
sql_query_info = SELECT * FROM bill WHERE id=$id
}
Here's the index
index bills
{
source = bill_src
path = /var/data/bills
docinfo = extern
charset_type = sbcs
}
I'm trying to use extended match mode. It seems that title and summary are fine but the official_title, the state and the chamber fields are ignored in the index. So for example if I do:
#official_title Affordable Care Act
I get:
query error: no field 'official_title' found in schema
but the same query with #summary produces results. Any ideas what I'm missing?
EDIT
Here's the table I'm trying to index:
+--------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| bt50_id | int(11) | YES | MUL | NULL | |
| type | varchar(10) | YES | | NULL | |
| title | varchar(255) | YES | | NULL | |
| official_title | text | YES | | NULL | |
| summary | text | YES | | NULL | |
| congresscritter_id | int(11) | NO | MUL | NULL | |
| last_action | datetime | YES | | NULL | |
| sunlight_id | varchar(45) | YES | | NULL | |
| number | int(11) | YES | | NULL | |
| state | char(2) | YES | | NULL | |
| chamber | varchar(45) | YES | | NULL | |
| session | varchar(45) | YES | | NULL | |
| featured | tinyint(1) | YES | | 0 | |
| source_url | varchar(255) | YES | | | |
+--------------------+--------------+------+-----+---------+----------------+
I seem to have fixed the problem, though I'll admit this is all dumb luck so it might not be a root cause:
First I thought maybe it didn't like the order of the fields in the query I have the only attribute field last so I decided to move it to after the ID:
SELECT id, UNIX_TIMESTAMP(last_action) AS bill_date, \
title,official_title,summary,state,chamber, FROM bill
This did not fix the problem.
Secondly, I noticed all the example date fields are converted using UNIX_TIMESTAMP and then aliased to the same name, so instead of UNIX_TIMESTAMP(last_action) AS bill_date I changed it to UNIX_TIMESTAMP(last_action) AS last_action ... the first attempt tripped me up though because it still wasn't working.
Finally I dropped the date altogether and added each field successfully (re-indexing and testing each time). Each time it worked and finally I added the date field on the end and I was able to sort by it and search all the fields. So the final query is:
SELECT \
id,title,official_title,summary,state,chamber, \
UNIX_TIMESTAMP(last_action) AS last_action FROM bill
It seems that attribute fields must come after the full text fields and aliases must be the same name as the actual field name. I find it strange that the date field seemed fine but other fields suddenly disappeared (randomly!).
I hope this helps someone else though I feel it might be some kind of isolated bug that doesn't affect many people. (This is on OSX and sphinx was compiled by hand)
Little rusty on sphinx, but believe in your source { } clause needs a sql_field_string definition.
source bill_src : dbconfig
{
sql_query = \
SELECT \
id,title,official_title,summary,state,chamber, \
UNIX_TIMESTAMP(last_action) AS bill_date \
FROM bill
sql_attr_timestamp = bill_date
sql_field_string = official_title
sql_query_info = SELECT * FROM bill WHERE id=$id
}
According to http://sphinxsearch.com/docs/1.10/conf-sql-field-string.html the sql_field_string declaration will index and store the string for referencing. That's different from a sql_attr_string, which is stored but not indexed.
i've created financialTrack table in mysql, to log inserted rows in financial table, and then create this trigger to doing it:
CREATE TRIGGER INS_after_financ
AFTER INSERT ON `financial` FOR EACH ROW
BEGIN
INSERT INTO `financialTrack` (user, changedValue) VALUES (NEW.user, NEW.Value);
END;
these are my tables structure :
TABLE NAME: financial
+--------------+--------------+-------+-------+
| Column | Type | Null | AI |
+--------------+--------------+-------+-------+
| id | int(10) | FALSE | TRUE |
| user | VARCHAR(40) | FALSE | |
| Value | BIGINT(12) | FALSE | |
+--------------+--------------+-------+-------+
TABLE NAME: financialTrack
+--------------+--------------+-------+-----------------+
| Column | Type | Null | Def.Value |
+--------------+--------------+-------+-----------------+
| user | VARCHAR(40) | FALSE | |
| changedValue | BIGINT(12) | FALSE | |
| ts | timestamp | FALSE |CURRENT_TIMESTAMP|
+--------------+--------------+-------+-----------------+
do you have any suggestion to fill user field in financialTrack table with PHP script and remove user column from financial table ?
There are several ways to approach this task, but this lecture will surely help you to learn the basics of handling database queries with PHP: http://php.net/manual/en/book.pdo.php.
PDO extension is currently quite popular and preferred over the other native mysql and mysqli extensions. You will find some other useful information by searching for PDO on stackoverflow.