Showing posts with label MySQL. Show all posts
Showing posts with label MySQL. Show all posts

Interview Questions and Answers

Abstract class vs Interface

An interface is an empty shell, there are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.

// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();

int getFuel();
}

// my team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

int fuel;

void run()
{
print("Wrroooooooom");
}


int getFuel()
{
return this.fuel;
}
}

Abstract Class- Abstract classes are those classes which can not be directly initialized. Or in other word we can say that you can not create object of abstract classes. Abstract classes always created for inheritance purpose. You can only inherit abstract class in your child class. Lots of people say that in abstract class at least your one method should be abstract.


// I say all motor vehicles should look like this :
abstract class MotorVehicle
{

int fuel;

// they ALL have fuel, so why not let others implement this?
// let's make it for everybody
int getFuel()
{
return this.fuel;
}

// that can be very different, force them to provide their
// implementation
abstract void run();


}

// my team mate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("hurrr");
}
}


The key technical differences between an abstract class and an interface are:

  • Abstract classes can have constants, members, method stubs (methods without a body) and defined methods, whereas interfaces can only have constants and methods stubs.
  • Methods and members of an abstract class can be defined with any visibility, whereas all methods of an interface must be defined as public (they are defined public by default).
  • When inheriting an abstract class, a concrete child class must define the abstract methods, whereas an an abstract class can extend another abstract class and abstract methods from the parent class don't have to be defined.
  • Similarly, an interface extending another interface is not responsible for implementing methods from the parent interface. This is because interfaces cannot define any implementation.
  • A child class can only extend a single class (abstract or concrete), whereas an interface can extend or a class can implement multiple other interfaces.
  • A child class can define abstract methods with the same or less restrictive visibility, whereas a class implementing an interface must define the methods with the exact same visibility (public).

MySQL Cluster

MySQL Cluster is a technology providing shared-nothing clustering and auto-sharding for the MySQL database management system. It is designed to provide high availability and high throughput with low latency, while allowing for near linear scalability.[2]MySQL Cluster is implemented through the NDB or NDBCLUSTER storage engine for MySQL ("NDB" stands for Network Database).

MySQL Cluster is designed around a distributed, multi-master ACID compliant architecture with no single point of failure. MySQL Cluster uses automatic sharding (partitioning) to scale out read and write operations on commodity hardware and can be accessed via SQL and Non-SQL (NoSQL) APIs

Database Index

A database index is a data structure that improves the speed of operations in a table. Indexes can be created using one or more columns, providing the basis for both rapid random lookups and efficient ordering of access to records.

Indexes are also type of tables, which keep primary key or index field and a pointer to each record into the actual table.

The users cannot see the indexes, they are just used to speed up queries and will be used by Database Search Engine to locate records very fast.

INSERT and UPDATE statements take more time on tables having indexes where as SELECT statements become fast on those tables. The reason is that while doing insert or update, database need to insert or update index values as well.

Unique Key

A unique index means that two rows cannot have the same index value.
Syntax -

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...);
 
ALTER TABLE tbl_name ADD UNIQUE index_name (column_list) 

Primary Key

A primary key uniquely identify a row in the table. A table can have only one Primary Key.
Syntax-
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)

Full Text Index

FULLTEXT indexes are only useful for full text searches done with the MATCH() / AGAINST() clause.
Synatx-
ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list)

Method Overriding vs Method Overloading



Creating Trigger in MySQL

Create trigger with multiple if else

CREATE DEFINER=`root`@`localhost` TRIGGER trigger_example
   BEFORE DELETE ON tbl_users
   FOR EACH ROW
BEGIN
       IF OLD.userId = 1126 THEN
         INSERT INTO tbl_archive_users ( userID, deleted_date, by) VALUES (OLD.userID,SYSDATE(),1126);
       ELSEIF OLD.userId = 1127 THEN
         INSERT INTO tbl_archive_users (userID, deleted_date,by) VALUES (OLD.userID,SYSDATE(), 1127);
       END IF;
END

Create Trigger table

DELIMITER //
CREATE TRIGGER archive_users
BEFORE DELETE ON tbl_users
  FOR EACH ROW
     BEGIN
        INSERT INTO tbl_archive_users (`userId`,`fname`,`lname`,`email`)
        VALUES(OLD.userId,OLD.fname,OLD.lname,OLD.email);
END; //
DELIMITER ;

Common MySQL Interview Questions


Here's a handy query for finding duplicates in a table. Suppose you want to find all email addresses in a table that exist more than once:

SELECT email,
COUNT(email) AS NumOccurrences
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )
You could also use this technique to find rows that occur exactly once:

SELECT email
FROM users
GROUP BY email
HAVING ( COUNT(email) = 1 )

-----------add comments to a column ---------

ALTER TABLE tbl_commety_members modify `member_type` TINYINT( 1 ) COMMENT 'id of user'


// to select a column with serial no which doesn't exist in mysql table
SET @rownum:=0; SELECT @rownum:=@rownum+1 AS id, names FROM table_name;


-----------to fromat date in dd/mm/yyyy format--------------------


SELECT remarks, date_FORMAT(payment_date,'%d/%m/%Y') FROM tbl_payment


--------------------------group by----------------------------


select count(tbl_property.city) as ctr,tbl_city.city from tbl_property left join tbl_city on (tbl_property.city=tbl_city.id) where tbl_property.status=1 group by tbl_property.city order by ctr desc limit 0,8


-------------------------count max id from union of two table---------------


select certificate_no from (select certificate_no from tbl_austfumigation order by certificate_no desc limit 0,1) as a
union
select certificate_no from (select certificate_no from tbl_fumigation order by certificate_no desc limit 0,1) as b
order by certificate_no desc limit 0,1



-----------------------Count co of columns in a table------------
SELECT count(*) FROM information_schema.`COLUMNS` C
WHERE table_name = 'tablename'
AND TABLE_SCHEMA = "databasename"

--------------------rearrange columns ---------------
ALTER table tbl_tour MODIFY COLUMN days tinyint(4) AFTER package;


-----------------replace a part of a str ------------


http://www.demourl.com/RTL.asp?Name=StringReplace


REPLACE(str,from_str,to_str)

Returns the string str with all occurrences of the string from_str replaced by the string to_str. REPLACE()performs a case-sensitive match when searching for from_str.

mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
    -> 'WwWwWw.mysql.com'
This function is multi-byte safe.

UPDATE MyDB.MyTable
SET MyDB.MyTable
= REPLACE(MyDB.MyTable.MyField,'OldString','NewString')
WHERE MyDB.MyTable.MyField like '%OldString%';

--------------------load data from csv-------------------------

load data local infile 'uniq.csv' into table tblUniq fields terminated by ','
enclosed by '"'
lines terminated by '\n'
(uniqName, uniqCity, uniqComments)

----------- format date time datetime is the name of the field------------------

select tbl_order.*, DATE_FORMAT(datetime,'%d/%m/%Y %h:%m:%s %p') as tt from tbl_order

-------------rearrange column after cretaing table--------------------------

alter table `tbl_maintenance` modify column vehicle_id bigint(20) after id



Introduction to stored procedure


What is stored procedure?

A stored procedure is a piece of SQL statements stored inside the database server.
  • Typically stored procedures help increase the performance of the applications. Once created, stored procedures are compiled and stored in the database. However MySQL stored procedures are compiled on demand. After compiling a stored procedure, MySQL puts it to a cache and maintains its own stored procedure cache for every single connection. If an application uses a stored procedure multiple times in a single connection, the compiled version is used, otherwise the stored procedure works like a query.
  • Stored procedures reduces the traffic between application and database server because instead of sending multiple SQL statements, the application has to send only name and parameters of the stored procedure.
  • Can be tested independent of the application.
  • Limit direct access to tables via defined roles in the database.

Disadvantages

  • Using a lot of stored procedures will consume lots of memory usage.
  • It is difficult to debug stored procedures.

What are alternatives to Stored Procedures?

Because Stored Procedures are not always the perfect solution nor do they satisfy all the needs of all developers, other solutions exist that attempt to provide most of what a developer wants to do when accessing a database backend.
These include:

In-line or Parameterized Queries

These are written within the application code itself

Object Relational Mapping (ORM)

Provides an abstraction to the database without having to manually write data access classes. At this point, most all major platforms offer some form of ORM software, as illustrated at this site .

How to create a procedure in MySQL?

IN parameter


delimiter $$
Create PROCEDURE `getUsersByEmail`(
   IN email1 VARCHAR(215)
)
BEGIN
  SELECT name FROM tbl_user WHERE email = email1;
END $$
delimiter ;
call getUsersByEmail('aryan@gmail.com');

OUT parameter

DELIMITER $$
Create PROCEDURE `getUsersById`(
  IN id1 int(10),
  OUT name1 varchar(200))
BEGIN
  SELECT name INTO name1 FROM tbl_user WHERE id= id1;
END $$
DELIMITER ;

call getUsersById(14,@name);
select @name;


Delete/drop a procedure instead of alter

DROP PROCEDURE IF EXISTS `getUsersByEmail`;
delimiter $$
Create PROCEDURE `getUsersByEmail`(
   IN email1 VARCHAR(215)
)
BEGIN
  SELECT name FROM tbl_user WHERE email = email1;
END $$
delimiter ;

How to show all procedures created in a database?

SHOW PROCEDURE STATUS;
SHOW FUNCTION STATUS;

How to create a procedure which return multiple rows?

drop procedure if exists getusers;
delimiter $$
CREATE PROCEDURE `getUsers`()
BEGIN
    SELECT * FROM tbl_user limit 1,10;
END $$
delimiter ;

call getUsers();

Using PHP to call a stored procedure

create table
CREATE TABLE IF NOT EXISTS `tbl_user` (
`id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `contact` varchar(25) DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `modified` date DEFAULT NULL,
  `created` date DEFAULT NULL,
  `image` varchar(255) DEFAULT NULL,
  `role` int(11) DEFAULT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;

Insert some rows

INSERT INTO `tbl_user` (`id`, `name`, `email`, `password`, `contact`, `status`, `modified`, `created`, `image`, `role`)
VALUES
(1, 'aryan014', 'aryan@gmail.com', '2a$10$nU4', '999999999', NULL, '2014-10-27', '2014-10-19', NULL, 1),
(2, 'Aryan 022', 'aryan022@gmail.com', '2a$10$8BW5', NULL, NULL, '2014-10-19', '2014-10-19', 'profile.jpg', 6);

Now create procedure

DELIMITER $$
CREATE PROCEDURE getUserRole(
  in p_uId int(11),
  out p_uRole varchar(50)
)
BEGIN
DECLARE role_name varchar(50);
SELECT role INTO role_name FROM tbl_user WHERE id = p_uId;

IF (role_name=1) THEN
  SET p_uRole = 'SUPERADMIN';
ELSEIF (role_name <= 5 AND role_name >= 2) THEN
  SET p_uRole = 'ADMIN';
ELSEIF role_name < 10 THEN 

  SET p_uRole = 'USER';
END IF;
END$$

Now call with php & pdo

<?php 
$userId = 1;
try {
    $conn = new PDO("mysql:host=localhost;dbname=cakephp", "root", "admin");
    $sql = 'CALL getUserRole(:id,@role)';
    $stmt = $conn->prepare($sql);
 
    $stmt->bindParam(':id', $userId , PDO::PARAM_INT);
    $stmt->execute();
    $stmt->closeCursor();
    $r = $conn->query("SELECT @role AS role")->fetch(PDO::FETCH_ASSOC);
    if ($r) {
        echo sprintf('User #%d is %s', $userId, $r['role']);
    }
} catch (PDOException $e) {
    die("Error occurred:" . $e->getMessage());
}

Introduction to PDO

What is PDO and Why to use PDO?

Well, PDO stands for PHP Data Objects, an advanced approach to connect to database not only mysql but several others. Here is a list of database supported by PDO-

Micro Soft SQL Server

MySQL

PostgreSQL

Oracle

Sqlite

IBM DB2

Firebird

INFORMIX etc.


The PDO extension defines a lightweight, consistent interface for accessing databases in PHP. It means that, regardless of which database you're using, use the same functions to issue queries and fetch data. There is no need to rewrite your queries again when you change your database.


Why to use PDO?

One can ask that why to use pdo? What are benefits of using PDO? Sure there are reasons to prefer PDO over mysql_* functions.


Prepared statement

Stored Procedure

Transaction

Multiple Query execution

Named Parameter

Object Mapping

Multiple Database Support

Security from SQL Injection Attack

Better Error Handling


How to connect to database?

Always try to connect inside try and catch block like this


$db="mysql";


$databasetype="mysql";


try {

switch($databasetype){

case "mysql": $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password;

//for persistent connection

case "mysqlp": $dbh = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password,array(PDO::ATTR_PERSISTENT => true));

case "postgres": $dbh = new PDO("pgsql:dbname=$dbname;host=$hostname", $username, $password);

case "sqlite": $dbh = new PDO("sqlite:/path/to/database.sdb");

case "sqlitememory": $dbh = new PDO("sqlite::memory");//to create tables in memory

case "firebird": $dbh = new PDO("firebird:dbname=localhost:D:\Programs\Firebird\DATABASE.FDB", "SYSDBA", "masterkey");

case "informix": $dbh = new PDO("informix:DSN=InformixDB", $username, $password);

case "oracle": $dbh = new PDO("OCI:", $username, $password);

//new PDO("OCI:dbname=$dbname;charset=UTF-8", $username, $password);

case "odbc": $dbh = new PDO("odbc:Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\accounts.mdb;Uid=Admin");

case "dblib": $dbh = new PDO ("dblib:host=$hostname:$port;dbname=$dbname",$username,$password);

case "ibm": $dbh = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=accounts; HOSTNAME=1.2.3,4;PORT=56789;PROTOCOL=TCPIP;", $username, $password);

}


$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

// which tells PDO to disable emulated prepared statements and

// use real prepared statements. This makes sure the statement

// and the values aren't parsed by PHP before sending it to the MySQL server

// (giving a possible attacker no chance to inject malicious SQL).


$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch(PDOException $e){

echo $e->getMessage();

}



The above example shows you how to connect to different database using simple approach with PDO.

The best way is to use a class for database connection and include this class in your every page.


<?php

/**

* db class used for connecting to databse with pdo

*

*/


class db {


private static $con=null;


private function __construct() {


}


public static function con(){


if( !self::$con){

if($_SERVER['HTTP_HOST']=='localhost'){

self::$con = new PDO("mysql:host=localhost; dbname=mydb", "root", "admin");

} else{

self::$con = new PDO("mysql:host=localhost; dbname=my_serverdb", "myserverusername", "myserverpass");

}


self::$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

// which tells PDO to disable emulated prepared statements and use real prepared statements.

// This makes sure the statement and the values aren't parsed by PHP before sending it to the

// MySQL server (giving a possible attacker no chance to inject malicious SQL).


self::$con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

}


return self::$con;

}


private function __clone() {


}

}



and call like this


db::con()->query("select * from emp");



We will assume this method in our whole tutorials.


Error Handling

PDO has three error handling modes.

PDO::ERRMODE_SILENT : acts like mysql_* where you must check each result and then look at errorInfo() to get the error details.

PDO::ERRMODE_WARNING : throws PHP Warnings

PDO::ERRMODE_EXCEPTION : throws PDOException. It acts very much like or die(mysql_error()); when it isn't caught, but unlike or die() the PDOException can be caught and handled gracefully like the code below shows-


try {

db::con()->query('hi'); //invalid query!

} catch(PDOException $ex) {

echo "An Error occured!"; //user friendly message

some_logging_function($ex->getMessage());

}


CRUD operations with PDO


Insert


$count = db->con()->exec("INSERT INTO emp(name, email) VALUES ('RN', 'abc@pqr.com')");


Update


$count = db->con()->exec("INSERT INTO emp(name, email) VALUES ('RN', 'abc@pqr.com')");


Delete


$count = db->con()->exec("DELETE from emp where id=1");


Select


froeach( db->con()->query("SELECT * FROM emp where id>1 ") as $row){

echo $row['name'];

}


$stmt = db::con()->query('SELECT * FROM table');


while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

echo $row['field1'].' '.$row['field2'];

}


$stmt = db::con()->query('SELECT * FROM table');

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

print_r($results);


What are Fetch Modes?

You may see above PDO::FETCH_ASSOC whith fetchAll() and fetch() methods. So what they actually means?


PDO::FETCH_ASSOC: This tells PDO to return the rows as an associative array with the field names as keys

PDO::FETCH_NUM : returns the row as a numerical array

PDO::FETCH_BOTH: This is default behaviour and returns an array, indexed by both column-name and numeric-indexed. eg. $row['name'] and $row['1']

PDO::FETCH_BOUND: Returns TRUE and assigns the values of the columns in your result set to the PHP variables to which they were bound.

PDO::FETCH_CLASS: Returns a new instance of the specified class.

PDO::FETCH_OBJ: Returns an object, with property names that correspond to the columns. eg. $row->name


Getting Row Count

Instead of using mysql_num_row use rowCount()


$stmt = db::con()->query('SELECT * FROM table');


$row_count = $stmt->rowCount();


echo $row_count.' rows total';


Getting the Last Insert Id

$result = db::con()->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')");

$insertId = db::con()->lastInsertId();//on database connection object not on result object


Prepared Statment

A prepared statement is a pre-compiled SQL statement that accepts zero or more named parameters. Its very useful when using the same statement or query multiple times with different parameters, or field values. It also helps prevent SQL injection by calling the PDO::quote() method internally.


Example.


$stmt = db::con()->prepare("SELECT * FROM table WHERE id=? AND name=?");

$stmt->bindValue(1, $id, PDO::PARAM_INT);

$stmt->bindValue(2, $name, PDO::PARAM_STR);

$stmt->execute();

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Named Placeholders

If you have lots of parameters to bind, use named placeholders instead of the '?' use : with column name like


$stmt = db::con()->prepare("SELECT * FROM table WHERE id=:id AND name=:name");

$stmt->bindValue(':id', $id, PDO::PARAM_INT);

$stmt->bindValue(':name', $name, PDO::PARAM_STR);

$stmt->execute();

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);



or execute with array can also bind


$stmt = db::con()->prepare("SELECT * FROM table WHERE id=:id AND name=:name");

$stmt->execute(array(':name' => $name, ':id' => $id));

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Transactions

A PDO transaction begins with the with PDO::beginTransaction() method. This method turns off auto-commit and any database statements or queries are not committed to the database until the transaction is committed with PDO::commit. When PDO::commit is called, all statements/queries are enacted and the database connection is returned to auto-commit mode.


try {

db::con()->beginTransaction();


db::con()->exec("SOME QUERY");


$stmt = db::con()->prepare("SOME OTHER QUERY?");

$stmt->execute(array($value));


$stmt = db::con()->prepare("YET ANOTHER QUERY??");

$stmt->execute(array($value2, $value3));


db::con()->commit();

} catch(PDOException $ex) {

//Something went wrong rollback!

db::con()->rollBack();

echo $ex->getMessage();

}


Object Mapping

One of the neatest aspects of PDO is that it gives us the ability to map the query results to a class instance, or object. See example below:


class Employee {

public $first_name;

public $last_name;


public function full_name()

{

return $this->first_name . ' ' . $this->last_name;

}

}


try {


$result = db::con()->query('SELECT * FROM someTable');


# Map results to object

$result->setFetchMode(PDO::FETCH_CLASS, 'Employee ');


while($user = $result->fetch()) {

# Call our custom full_name method

echo $user->full_name();

}

} catch(PDOException $e) {

echo 'Error: ' . $e->getMessage();

}


What Is an SQL Injection Attack?

An SQL injection attack is when a user injects SQL commands in to an unprotected SQL query. This can lead to a number of issues, including modifying rows you didn't intend for the user to modify, dropped tables, deleted rows, and access to possibly sensitive data like this.


SELECT secret_data FROM mytable WHERE na,e= 'x' OR x'='x


How to prevent SQL In-jection attack?

Use prepared statement


$stmt = db::con()->prepare("SELECT * FROM table WHERE name=:name");


$stmt->bindValue(':name', $name, PDO::PARAM_STR);


$stmt->execute();


$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

Control Flow Functions

 Example:-

SELECT                --- here (below) condition is defined first then it is matched with when statement
    CASE 2               --- means condition here 2 is condition to be checked
    WHEN 1 THEN 'one'    --- 2 will be matched with 1 if matched then one will be output
    WHEN 2 THEN 'two'     --- 2 (of CASE 2) will be matched with 2(of WHERE) .if matched two will be output
    WHEN 3 THEN 'three'   --- 2 will be matched with 3
    ELSE 'others'         --- if no match  found others will be output
END;                  --- end of the loop


Query output : 'two'

 Example :-

SELECT                     --- here (below) condition is not defined first. It is checked with when statement
    CASE WHEN 1>0 THEN 'true'  --- checking if 1 is greater than 0 if it is, true will outputted
    ELSE 'false'           --- else false will outputted
END;              --- end of the loop


Query output : 'true'
 
Example :-

SELECT
    CASE BINARY 'B'     --- here condition is checked against binary means here B and b are not equal.
    WHEN 'a' THEN 1    --- if condition is not matched then null will outputted
    WHEN 'b' THEN 2
END;

Query output : NULL

These are three variations of case statement in MySQL.

The if() function:-

If expr1 is TRUE  then IF() returns expr2; otherwise it returns expr3.

IF() returns a numeric or string value, depending on the context in which it is used.

Example:-

SELECT IF( 1 > 2, 2, 3 ); ---here first condition is checked i.e. if 1 is greater than 2, if it is 2 is outputted else 3 is outputed


Query output : 3

Example :-

SELECT IF( 1< 2, 'yes', 'no' );

Query output : 'yes'

If only one of expr2 or expr3 is explicitly NULL, the result type of the IF() function is the type of the non-NULL expression.

The default return type of IF() is calculated as follows;- expr2 or expr3 returns a string then return type is string expr2 or expr3 returns a floating-point value then return type is floating-point expr2 or expr3 returns an integer then return type is integer