PHP获取某个表与其他表的关联关系算法
如图 电影movie有多个附表,如果通过movie表来找出多个与之关联的表。
本算法规则:
- 外键写法必须是X_id;
- A与B 1对多关系,中间表表名必须是A_B,且A_B,必须包含A_id,B_id外键;
算法如下:
---------------------更新-----------------------------------------------
function findRelation($db=['dbname','user','pwd','host'],$current,$father='')
{
static $pdo;
if(empty($father))
{
$pdo=new PDO("mysql:host=".(isset($db[3])?$db[3]:'localhost').";dbname={$db[0]}",$db[1],(isset($db[2])?$db[2]:''));
$pdo->exec('set names utf8');
} //临时数组,保存下面运行得出的数据
$tp=[]; //当前表的所有字段信息
$self=$pdo->query('show full columns from '.$current); //当前表是否中间表
$is_middle=0; //检查当前表是否有附表id字段
while($row = $self -> fetch())
{
//如果有发现以xxx_id命名的外键
if(stripos($row['Field'],'_id')!==FALSE)
{
//获取附表名
$extName=str_ireplace('_id','',$row['Field']); //如果当前的”附表“ 名是父表名,记录保存字段
if($extName==$father)
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],'parent_index']; continue;
}
else
{
//当前表包含有 当前表外键中的附表名(即main_extName 包含有 extName_id),则此表为中间表
if(strpos($current,$extName)!==FALSE)
$is_middle=1; //记录字段信息
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],'next_index']; //继续往下寻找附表关系
$tp[$extName]=findRelation($db,$extName,$current); }
}
else//没发现外键,记录当前字段
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Comment'],$row['Key']];
}
} //记录当前表是否中间表
if($is_middle)
$tp['_type']='middle';
else
$tp['_type']='content'; //获取当前表注释
$cms=$pdo->query("show table status from {$db[0]} where name='{$current}'");
$one=$cms->fetch();
$tp['_comment']=$one['Comment']; //扫描以【当前表】_为开头的附表
$exts=$pdo->query('show tables like "'.$current.'_%"');
while($ext = $exts -> fetch())
{
//往下寻找当前表与每个附表的关系
$tp[$ext[0]]=findRelation($db,$ext[0],$current);
} return $tp;//返回已记录的关联关系和字段信息
} echo '<pre>';
print_r(['movie'=>findRelation(['movieshop','root'],'movie')]);
echo '</pre>';
上述算法得出的数据格式如下:
/* ([主表]=>)[
[_field]=>[
[字段名] => [
[0] => 字段类型
[1] => 默认值
[2] => 字段注释
[3] => 字段索引
],
.....
]
, [_type]=>middle/content(多对多中间表/1对多内容表,不是中间表可忽略)
,
[_comment]=>表注释
,
[附表名]=>[
[_field]=>[
[字段名] => [
[0] => 字段类型
[1] => 默认值
[2] => 字段注释
[3] => 字段索引
],
.....
],
[_type]=>middle/content(多对多中间表/1对多内容表,不是中间表可忽略)
,
[_comment]=>表注释
,
[附表名]=>[
.............
]
,
...............
]
,
..........
] */
------------------------------------------------------------------------------旧版---------------------------------------------------------------------------------------
<?php /*
2016-11-03
GaZeon -------------寻找表关系方法--------------- 主表:main 附表格式:main_extName 可能存在的表:extName 判断主附的对应关系方法: 如果main 有 extName_id 则 main与main_extName 为1对1关系 如果main_extName 【有 且只有 main_id外键】或 【main_extName 有其他外键但不包含extName_id外键 】 则 main与main_extName 为1对多关系 如果main_extName 有 main_id外键,且有 extName_id 外键,则 main与 extName为多对多关系 ,main_extName为中间表 与main为1对多关系 1,获取【当前表】的所有字段,并循环字段查找_id结尾的外键
{
2,如果查找到【当前表】的外键,则判断【外键所在的表】是否【当前表】的【上一级表】:
[如果是,则【外键所在的表】为中间表,【当前表】与【外键所在的表】为1对多关系,跳过本次进入下次循环];
[如果不是,则【当前表】与【外键所在的表】为1对多关系,查找这个【外键所在的表】],
}
3,【当前表】外键查找完后,扫描以【当前表】_为开头的表:
[如果有,则循环轮流进入1程序];
4,没有,当前关联关系到达最终点,返回本次运行得出的关系信息。 -----------------------------------------------------
如果一个表没有任何外键
如果这个表没有附表,则为最终表
如果这个表有附表,则查找其附表,继续寻找其表的关联关系 */
$pdo=new PDO('mysql:host=localhost;dbname=MovieShop','root','');
$pdo->exec('set names utf8');
$relation=[]; function findRelation($current,$father='')
{
global $pdo;
global $relation; //临时数组,保存下面运行得出的数据
$tp=[]; //当前表的所有字段信息
$self=$pdo->query('show full columns from '.$current); //当前表是否中间表
$is_middle=0; //检查当前表是否有附表id字段
while($row = $self -> fetch())
{
//如果有发现以xxx_id命名的外键
if(stripos($row['Field'],'_id')!==FALSE)
{
//获取附表名
$extName=str_ireplace('_id','',$row['Field']); //如果当前的”附表“ 名是父表名,记录保存字段
if($extName==$father)
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],'parent_index']; continue;
}
else
{
//当前表包含有 当前表外键中的附表名(即main_extName 包含有 extName_id),则此表为中间表
if(strpos($current,$extName)!==FALSE)
$is_middle=1; //记录字段信息
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],'next_index']; //继续往下寻找附表关系
$tp[$extName]=findRelation($extName,$current); }
}
else//没发现外键,记录当前字段
{
$tp['_field'][$row['Field']]=[$row['Type'],$row['Default'],$row['Key']];
}
} //记录当前表是否中间表
if($is_middle)
$tp['_type']='middle';
else
$tp['_type']='content'; //扫描以【当前表】_为开头的附表
$exts=$pdo->query('show tables like "'.$current.'_%"');
while($ext = $exts -> fetch())
{
//往下寻找当前表与每个附表的关系
$relation[$current][$ext[0]]=findRelation($ext[0],$current);
} return $tp;//返回已记录的关联关系和字段信息
} findRelation('movie'); echo '<pre>';
print_r($relation);
echo '</pre>';
有bug请联系本人,转载需注明出处。
PHP获取某个表与其他表的关联关系算法的更多相关文章
- [js开源组件开发]query组件,获取url参数和form表单json格式
query组件,获取url参数和form表单json格式 距离上次的组件[js开源组件开发]ajax分页组件一转眼过去了近二十天,或许我一周一组件的承诺有了质疑声,但其实我一直在做,只是没人看到……, ...
- 获取SQLSERVER所有库 所有表 所有列 所有字段信息
最近想起来做一个项目代码生成器,直接生成底层代码.. 这免不了要先行读取数据库已有的信息.. 废话不多说..开整.. SELECT NAME FROM MASTER..SYSDATABASES --读 ...
- SQL获取所有数据库名、表名、储存过程以及参数列表
SQL获取所有数据库名.表名.储存过程以及参数列表 1.获取所有用户名:SELECT name FROM Sysusers where status='2' and islogin='1'islogi ...
- sql 2000以及2005以上获取数据库中所有的表(不包括系统表)
---------------------------------------------------------------------------- --sql 2005以上数据库 --- 获取数 ...
- jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
jquery不能是使用普通的for循环 因为普通的for循环通过下表获取对象 如果通过下表获取对象的话 会转成dom对象
- Oracle 获取 某个表的建表SQL
获取A表的创表SQL select dbms_metadata.get_ddl('TABLE','A') from dual
- Sqlserver获取所有数据库名,表信息,字段信息,主键信息,以及表结构等。
--获取所有数据库名: SELECT name FROM master..sysdatabases WHERE name NOT IN ( 'master', 'model', 'msdb', 'te ...
- sql脚本来获取数据库中的所有表结构了
sql脚本来获取数据库中的所有表结构了,代码如下: use AdventureWorks2008 go SELECT (case when a.colorder=1 then d.name else ...
- SqlServer中获取所有数据库,所有表,所有字段
原文:SqlServer中获取所有数据库,所有表,所有字段 一.获取所有数据库 select * from master.dbo.SysDatabases 二.获取某个库中所有表 SELECT * F ...
随机推荐
- 你不知道的this—JS异步编程中的this
Javascript小学生都知道了javascript中的函数调用时会 隐性的接收两个附加的参数:this和arguments.参数this在javascript编程中占据中非常重要的地位,它的值取决 ...
- 判断横屏竖屏,然后CSS重新计算
function hengshuping(){ if(window.orientation==180||window.orientation==0){ alert("竖屏状态!") ...
- hdfs中block的使用情况,副本所在情况等等
hadoop fsck /user/hive/warehouse/dataplat.db/hive_datacppa2xsourcendchinaraw/partitiondate=2016-11-2 ...
- 图文:通过sql server 连接mysql
1.在SQL SERVER服务器上安装MYSQL ODBC驱动; 驱动下载地址:http://dev.mysql.com/downloads/connector/odbc/ 2.安装好后,在管理工具- ...
- python lambda
匿名函数和lambda: lambda [args1,[args2]] : expression python 使用lambda来创建匿名函数,匿名函数不需要以标准的方式进行创建,但是作为函数,它们也 ...
- 祝贺 Linux 25 岁:25 个关于 Linux 的惊人真相!【转载】
作者:Javen Fang链接:https://zhuanlan.zhihu.com/p/22222383来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 25 年前的这 ...
- input的实时监控
<input id="phone" type="tel" placeholder="请输入手机号"> $("#phon ...
- 归一化交叉相关Normalization cross correlation (NCC)
归一化交叉相关Normalization cross correlation (NCC) 相关系数,图像匹配 NCC正如其名字,是用来描述两个目标的相关程度的,也就是说可以用来刻画目标间的相似性.一般 ...
- python中获取指定目录下所有文件名列表的程序
http://blog.csdn.net/rumswell/article/details/9818001 # -*- coding: utf-8 -*-#~ #------------------- ...
- 单元测试 逃不开的Done 与约定
关注单元测试有一段时间了,也做了些尝试然后就停了下来,寻找框架.方法.各种尝试 看得多,尝试的少, 关于框架分为两类,1是自动化测试工具类,1是js单元测试框架 关于自动化测试工具我尝试了http:/ ...