??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
Ҏ1Q?用SET PASSWORD命o
mysql -u root
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpass');
Ҏ2Q用mysqladmin
mysqladmin -u root password "newpass"
如果root已经讄q密码,采用如下Ҏ
mysqladmin -u root password oldpass "newpass"
Ҏ3Q?用UPDATE直接~辑user?/p>
mysql -u root
mysql> use mysql;
mysql> UPDATE user SET Password = PASSWORD('newpass') WHERE user = 'root';
mysql> FLUSH PRIVILEGES;
在丢失root密码的时候,可以q样
mysqld_safe --skip-grant-tables&
mysql -u root mysql
mysql> UPDATE user SET password=PASSWORD("new password") WHERE user='root';
mysql> FLUSH PRIVILEGES;
引言
数据库的设计范式是数据库设计所需要满的规范Q满些规范的数据库是z的、结构明晰的Q同Ӟ不会发生插入QinsertQ、删除(deleteQ和更新QupdateQ操作异常。反之则是ؕ七八p,不仅l数据库的编Eh员制造麻烦,而且面目可憎Q可能存储了大量不需要的冗余信息?br />
设计范式是不是很难懂呢?非也Q大学教材上l我们一堆数学公式我们当然看不懂Q也C住。所以我们很多h根本不按照范式来设计数据库?br />
实质上,设计范式用很形象、很z的话语p说清楚,道明白。本文将对范式进行通俗地说明,q以W者曾l设计的一个简单论坛的数据库ؓ例来讲解怎样这些范式应用于实际工程?br />
范式说明
W一范式Q?NFQ:数据库表中的字段都是单一属性的Q不可再分。这个单一属性由基本cd构成Q包括整型、实数、字W型、逻辑型、日期型{?br />
例如Q如下的数据库表是符合第一范式的:
字段1 | 字段2 | 字段3 | 字段4 |
字段1 | 字段2 | 字段3 | 字段4 | |
字段3.1 | 字段3.2 |
很显Ӟ在当前的M关系数据库管理系l(DBMSQ中Q傻瓜也不可能做ZW合W一范式的数据库Q因些DBMS不允怽把数据库表的一列再分成二列或多列。因此,你想在现有的DBMS中设计出不符合第一范式的数据库都是不可能的?br />
W二范式Q?NFQ:数据库表中不存在非关键字D对M候选关键字D늚部分函数依赖Q部分函C赖指的是存在l合关键字中的某些字D决定非关键字段的情况)Q也x有非关键字段都完全依赖于L一l候选关键字?
范式应用
我们来逐步搞定一个论坛的数据库,有如下信息:
Q?Q?用户Q用户名QemailQ主,电话Q联pd址
Q?Q?帖子Q发帖标题,发帖内容Q回复标题,回复内容
W一ơ我们将数据库设计ؓ仅仅存在表:
用户? | 主页 | 电话 | 联系地址 | 发帖标题 | 发帖内容 | 回复标题 | 回复内容 |
用户?/td> | 主页 | 电话 | 联系地址 | 发帖ID | 发帖标题 | 发帖内容 | 回复ID | 回复标题 | 回复内容 |
注意Q?br /> 当内存表中的数据大于max_heap_table_size讑֮的容量大时Qmysql会{换超出的数据存储到磁盘上Q因此这是性能大打折扣了Q所以我们还需要根据我们的实际情况调整max_heap_table_sizeQ例如在.cnf文g中[mysqld]的下面加入:
max_heap_table_size = 2048M
另外在徏表语句中q可以通过MAX_ROWS来控制表的记录数?br />
内存表用哈希散列烦引把数据保存在内存中Q因此具有极快的速度Q适合~存中小型数据库Q但是用上受到一些限Ӟ以下是蓝草用的一些感受?br />
1、heapҎ有用Lq接是可见的Q这使得它非帔R合做缓存?br />
2、仅适合使用的场合。heap不允怋用xxxTEXT和xxxBLOB数据cdQ只允许使用=?lt;=>操作W来搜烦记录Q不允许<?gt;?lt;=?gt;=Q;不支持auto_incrementQ只允许寚wI数据列q行索引Qnot nullQ?br />注:操作W??lt;=>?说明QNULL-safe equal.q个操作W和?”操作符执行相同的比较操作,不过在两个操作码均ؓNULLӞ其所得gؓ1而不为NULLQ而当一个操作码为NULLӞ其所得gؓ0而不为NULL?br />
3、一旦服务器重启Q所有heap表数据丢失,但是heap表结构仍然存在,因ؓheap表结构是存放在实际数据库路径下的Q不会自动删除。重启之后,heap被清空Q这时候对heap的查询结果都是空的?br />
4、如果heap是复制的某数据表Q则复制之后所有主键、烦引、自增等格式不复存在,需要重新添加主键和索引Q如果需要的话?br />
5、对于重启造成的数据丢失,有以下的解决办法Q?br /> a、在M查询之前Q执行一ơ简单的查询Q判断heap表是否存在数据,如果不存在,则把数据重新写入Q或者DROP表重新复制某张表。这需要多做一ơ查询。不q可以写成include文gQ在需要用该heap表的面随时调用Q比较方ѝ?br /> b、对于需要该heap表的面Q在该页面第一ơ且仅在W一ơ查询该表时Q对数据集结果进行判断,如果l果为空Q则需要重新写入数据。这样可以节省一ơ查询?br /> c、更好的办法是在mysql每次重新启动时自动写入数据到heapQ但是需要配|服务器Q过E比较复杂,通用性受到限制?br />
6、一些预期可能用到的sql语句
//如果表存在,则删?br />DROP TABLE IF EXISTS `abc`;
//复制整张表xyz为heap表abcQ包含所有数据)
CREATE TABLE `abc` type=heap select * from `xyz`;
//d主键id
ALTER TABLE `abc` ADD PRIMARY KEY (`id`);
//d索引username
ALTER TABLE `abc` ADD INDEX `abc` (`username`);
蓝草I间
/*q接Sqlite数据库,参数Qdbname->数据库名?/
function Open($dbname) {
if(!($this->link = @sqlite_open($dbname))) {
$this->halt('Can not Open to Sqlite');
}
}
/*执行sql语句Q返回对应的l果标识*/
function Query($sql) {
$this->querynum++;
if($query = @sqlite_query($this->link, $sql)) {
return $query;
} else {
$this->halt('Sqlite Query Error', $sql);
}
}
/*执行Insert Into语句Qƈq回最后的insert操作所产生的自动增长的id*/
function Insert($table, $iarr) {
$value = $this->InsertSql($iarr);
$this->Query('INSERT INTO "' . $table . '" ' . $value);
return sqlite_last_insert_rowid($this->link);
}
/*执行Update语句Qƈq回最后的update操作所影响的行?/
function Update($table, $uarr, $condition = '') {
$value = $this->UpdateSql($uarr);
if ($condition) {
$condition = ' WHERE ' . $condition;
}
$this->Query('UPDATE "' . $table . '"' . ' SET ' . $value . $condition);
return sqlite_changes($this->link);
}
/*执行Delete语句Qƈq回最后的Delete操作所影响的行?/
function Delete($table, $condition = '') {
if ($condition) {
$condition = ' WHERE ' . $condition;
}
$this->Query('DELETE "' . $table . '"' . $condition);
return sqlite_changes($this->link);
}
/*字W{为可以安全保存的sqlite|比如a'a转ؓa''a*/
/*
function EnCode($str) {
if (strpos($str, "\0") === false) {
if (strpos($str, '\'') === false) {
return $str;
} else {
return str_replace('\'', '\'\'', $str);
}
} else {
$str = str_replace("\0", '', $str);
if (strpos($str, '\'') === false) {
return $str;
} else {
return str_replace('\'', '\'\'', $str);
}
}
}
*/
function EnCode($str) {
return sqlite_escape_string($str);
}
/*可以安全保存的sqliteD{为正常的|比如a''a转ؓa'a*/
function DeCode($str) {
if (strpos($str, '\'\'') === false) {
return $str;
} else {
return str_replace('\'\'', '\'', $str);
}
}
/*对应的列和值生成对应的insert语句Q如Qarray('id' => 1, 'name' => 'name')q回("id", "name") VALUES (1, 'name')*/
function InsertSql($iarr) {
if (is_array($iarr)) {
$fstr = '';
$vstr = '';
foreach ($iarr as $key => $val) {
$fstr .= '"' . $key . '", ';
$vstr .= '\'' . $val . '\', ';
}
if ($fstr) {
$fstr = '(' . substr($fstr, 0, -2) . ')';
$vstr = '(' . substr($vstr, 0, -2) . ')';
return $fstr . ' VALUES ' . $vstr;
} else {
return '';
}
} else {
return '';
}
}
/*对应的列和值生成对应的insert语句Q如Qarray('id' => 1, 'name' => 'name')q回"id" = 1, "name" = 'name'*/
function UpdateSql($uarr) {
if (is_array($uarr)) {
$ustr = '';
foreach ($uarr as $key => $val) {
$ustr .= '"' . $key . '" = \'' . $val . '\', ';
}
if ($ustr) {
return substr($ustr, 0, -2);
} else {
return '';
}
} else {
return '';
}
}
/*q回对应的查询标识的l果的一?/
function GetRow($query, $result_type = SQLITE_ASSOC) {
return sqlite_fetch_array($query, $result_type);
}
/*清空查询l果所占用的内存资?/
function Clear($query) {
$query = null;
return true;
}
/*关闭数据?/
function Close() {
return sqlite_close($this->link);
}
function halt($message = '', $sql = '') {
$ei = sqlite_last_error($this->link);
$message .= '<br />Sqlite Error: ' . $ei . ', ' . sqlite_error_string($ei);
if ($sql) {
$sql = '<br />sql:' . $sql;
}
exit('DataBase Error.<br />Message: ' . $message . $sql);
}
}
struct olt_info
{
int olt_index;
int onu_on_line;
int ui_port1;
int ui_port2;
int ui_port3;
int ui_port4;
};
int my_callback(void * olt_temp, int argc, char * value[], char * name[])
{
int i;
struct olt_info * pdata = NULL;
pdata = (struct olt_info *)olt_temp;
puts("Here below is the code line:\n");
for (i = 0; i < argc; i++)
{
printf("%s == %s\n", name[i], value[i]);
}
puts("Code line over.\n");
pdata->olt_index = (int)atoi(value[0]);
pdata->onu_on_line = (int)atoi(value[1]);
pdata->ui_port1 = (int)atoi(value[2]);
pdata->ui_port2 = (int)atoi(value[3]);
pdata->ui_port3 = (int)atoi(value[4]);
pdata->ui_port4 = (int)atoi(value[5]);
return 0;
}
int main(int argc, char * argv[])
{
sqlite3 * olt_db = NULL;
int rc = 0;
int i;
char * err_msg = NULL;
char temp_msg[150];
struct olt_info * olt_temp= (struct olt_info *)malloc(sizeof(struct olt_info));
rc = sqlite3_open("olt.db", &olt_db);
if (rc)
{
fprintf(stderr, "Open database error, %s\n", sqlite3_errmsg(olt_db));
exit(1);
}
else
{
fprintf(stdout, "Open database OK.\n");
}
rc = sqlite3_exec(olt_db, "create table olt_tbl(olt_index integer primary key autoincrement, onu_on_line smallint, ui_port1 smallint, ui_port2 smallint, ui_port3 smallint, ui_port4 smallint);", NULL, NULL, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "Create table error, %s\n", err_msg);
exit(1);
}
else
{
fprintf(stdout, "Create table OK.\n");
}
for (i = 0; i < 6; i++)
{
sprintf(temp_msg, "insert into olt_tbl(onu_on_line, ui_port1, ui_port2, ui_port3, ui_port4) values(%d, %d, %d, %d, %d)", i * 16, i, i, i, i);
//rc = sqlite3_exec(olt_db, "insert into olt_tbl(onu_on_line, ui_port1, ui_port2, ui_port3, ui_port4) values(32, 1, 1, 1, 1);", NULL, NULL, &err_msg);
rc = sqlite3_exec(olt_db, temp_msg, NULL, NULL, &err_msg);
}
if (rc != SQLITE_OK)
{
fprintf(stderr, "Insert items failure, %s\n", err_msg);
}
else
{
fprintf(stdout, "Insert items OK.\n");
}
rc = sqlite3_exec(olt_db, "select * from olt_tbl where olt_index==4;", my_callback, olt_temp, &err_msg);
if (rc != SQLITE_OK)
{
fprintf(stderr, "Selete from olt_tbl failure, %s\n", err_msg);
exit(1);
}
else
{
fprintf(stdout, "Excute sql OK.\n");
}
printf("%d-%d-%d-%d-%d-%d\n", olt_temp->olt_index, olt_temp->onu_on_line,olt_temp->ui_port1,olt_temp->ui_port2,olt_temp->ui_port3,olt_temp->ui_port4);
free(olt_temp);
sqlite3_close(olt_db);
return 0;
}
其中my_callback(void * pdata, int argc, char * value[], char *name[])为回调函敎ͼ切记回调函数只能按照q种格式来定义参敎ͼ
W一个参Cؓ你的主调函数传递过来的指针Q?br /> W二个参Cؓ变量的个敎ͼ
W三个ؓ变量的|
W四个ؓ变量的名Uͼ
有两个问题需要注意:
一、这里面参数都是字符串类型,Ҏ您的需要作出强制类型{换即可?br /> 二、第一个参Cؓvoid *cdQ需要在你的回调函数里强制{换成需要的cd?br />
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1914908
Microsoft (R) Library Manager Version 6.00.8168 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. Creating library SQLITE.lib and object SQLITE.exp
q样成功地创徏了在WIN32E序中访问sqlite所需要的?可以用于链接WIN32E序.
到此所有用sqlite的准备工作已告罄.现在在MSVC6中新Z个Win32 Console Application工程,把sqlite.dll,sqlite.h和sqlite.lib文g复制到工E文件夹?把sqlite.h文g加入到项 目中,然后在Project Setting的Link中的对象库模块中增加sqlite.lib文g. 或者project->add to project->filesQ选择q个lib文g
然后修改加入如下代码卛_:
#include <IOSTREAM>
#include <STRING>
#include <SSTREAM>
#include <stdio.h>
#include "sqlite3.h"
using namespace std;
sqlite3* pDB;
int createTable()
{
char* errMsg;
std::string dropTab="drop table test_tab;";
string strSQL= "create table test_tab (f1 int, f2 long, f3 varchar(20));";
int res = sqlite3_exec(pDB,dropTab.c_str(),0,0, &errMsg);
if (res != SQLITE_OK)
{
std::cout << "执行SQL 出错." << errMsg << std::endl;
//return -1;
}
res = sqlite3_exec(pDB,strSQL.c_str(),0,0, &errMsg);
if (res != SQLITE_OK)
{
std::cout << "执行创徏table的SQL 出错." << errMsg << std::endl;
return -1;
}
else
{
std::cout << "创徏table的SQL成功执行."<< std::endl;
}
return 0;
}
int insert1()
{
char* errMsg;
int res = sqlite3_exec(pDB,"begin transaction;",0,0, &errMsg);
for (int i= 1; i < 100; ++i)
{
std::stringstream strsql;
strsql << "insert into test_tab values(";
strsql << i << ","<< (i+10) <<",'huyi'"<< ");";
std::string str = strsql.str();
cout << str <<endl;
res = sqlite3_exec(pDB,str.c_str(),0,0, &errMsg);
if (res != SQLITE_OK)
{
std::cout << "执行SQL 出错." << errMsg << std::endl;
return -1;
}
}
res = sqlite3_exec(pDB,"commit transaction;",0,0, &errMsg);
std::cout << "SQL成功执行."<< std::endl;
return 0;
}
int select1()
{
char* errMsg;
int nrow = 0, ncolumn = 0;
char **azResult; //二维数组存放l果
string strSQL= "select * from test_tab;";
/*
int res = sqlite3_exec(pDB,strSQL.c_str(),0,0, &errMsg);
if (res != SQLITE_OK)
{
std::cout << "执行SQL 出错." << errMsg << std::endl;
return -1;
}
else
{
std::cout << "SQL成功执行."<< std::endl;
}
*/
sqlite3_get_table(pDB, strSQL.c_str(), &azResult, &nrow, &ncolumn, &errMsg);
int i = 0;
for( i=0 ; i<( nrow + 1 ) * ncolumn ; i++ )
{
if (i>0 && i%ncolumn==0)
printf("\n");
printf( "%s ",azResult[i]);
}
printf("\n");
//释放?azResult 的内存空?br /> sqlite3_free_table( azResult );
sqlite3_close(pDB); //关闭数据?br /> return 0;
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "误入命令行参数Qsqlite数据库名." << std::endl;
return 0;
}
int res = sqlite3_open(argv[1], &pDB);
if( res ){
std::cout << "Can't open database: "<< sqlite3_errmsg(pDB);
sqlite3_close(pDB);
return -1;
}
res = createTable();
if (res != 0)
{
return 0;
}
res = insert1();
if (res != 0)
{
return 0;
}
select1();
return 0;
}