工欲善其事必先利其器---SQL在线可视化模型设计,(还可学习拖拽知识)
作为技术人员,在开发项目中,不可避免的要跟数据库打交道,一个完整的项目正常情况下是讨论完整体需求,有了大致的框框在脑海中后,是需要设计合理的数据库的,这时会有其他的专业的UML建模工具可以使用, 但是这种大型的专业化的UML建模工具,仅仅拿来建立数据库模型显得大材小用了,并且也太重量级,所以一般都不会轻易使用。多数人会选择直接在数据库软件中直接鼠标操作建表、填充列, 这样更是不方便, 故而很多人提到了VS中的codefirst方式, 直接在代码中建立数据库模型, 这种方式生成数据库之后,如果回头维护、查看都不太友好,甚至过了几个月之后你自己回头看都有可能不知道是什么意思。 这样我们就需要数据库说明。
常见的数据库说明都是word文档,类似如下:
这是很多公司或团队采用的, 但是我觉得这样还是不爽,假定你是一个接手人, 你拿着这样的表格,左边点开数据库,右边打开这个文档,瞄一眼数据库再瞄一眼这个表格,左右切换窗口,超级不爽啊。
另外一种更加直观的,正向思维的方式:
这样看起来是不是直观多了, 清楚明白的知道这个表的构成,直接在数据库中打开,不用切换窗口,它是建表脚本,也是一份详细直观的数据库说明文档, 后续对数据库进行修改、增加、删除结构都很直接、直观。
于是,我个人就弄了个自己用的方便的可视化的数据库设计的东西,当然最终是生成上述直观可读性高的脚本文件,今天把它写出来分享下。
我的环境是mvc3, 其实这个东西根本用不着MVC, 很简单,就一个页面大量的JS操作,提交到后台代码生成文件下载回本地。先看打开时:

默认加载一个空表,填写相应的名称之类的,字段、类型、默认值、备注信息等,+号增加一行,如果一行没有完成会提示:
点击新建表会增加一个表,整个筐筐内每个表模型可以任意拖动位置且高度会自适应。拖拽都是靠JS。整个界面代码如下:
 @{
     ViewBag.Title = "主页";
 }
 <div class="box">
        <div class="editmenu">
        <input  type="text" id="txtBaseName" value="@ViewBag.baseName"/>
        <input  type="text" id="txtBaseDes"  value="@ViewBag.baseDes"/>
        <input id="addTable" type="button"  value="新建表"/>
        <input id="getData" type="button" title="下载完整的TXT格式的数据库脚本" style="float:right;"   value="下载数据"/>
        </div>
         <div id="main" class="main">
             <div class="tbbox">
                 <div class="titletr" title="">
                     <span class="spleft">
                     <input value="XXX表" class="tbname"  type="text" />
                     </span>
                     <span class="title"></span>
                     <span class="spright"></span>
                 </div>
                 <div class="titletr" title="">
                     <span class="spleft">
                     名:<input  value="tb_1" class="tbname" type="text" />
                     </span>
                     <span class="title"></span>
                     <span class="spright">删除</span>
                 </div>
                 <table class="tablelist">
                     <tbody>
                         <tr>
                             <td>
                                 字段名
                             </td>
                             <td>
                                 类型
                             </td>
                             <td>
                                 默认值
                             </td>
                             <td>
                                 备注
                             </td>
                             <td style="border: 0">
                             </td>
                         </tr>
                         <tr>
                             <td>
                                 <input type="text" />
                             </td>
                             <td>
                                 <div class="sortdiv">
                                     <span  class="selspan">
                                         <select class="selsort">
                                             <option value="int">int</option>
                                             <option value="varchar(50)">varchar(50)</option>
                                             <option value="nvarchar(200)">nvarchar(200)</option>
                                             <option value="datetime">datetime</option>
                                             <option value="float">float</option>
                                             <option value="text">text</option>
                                             <option value="ntext">ntext</option>
                                         </select>
                                     </span>
                                     <input  value="int"  class="sortinput" />
                                 </div>
                             </td>
                             <td>
                               <input class="txtdef" type="text" />
                             </td>
                             <td>
                               <input type="text" />
                             </td>
                             <td id="tool" class="jiatr" style="border: 0">
                                +
                             </td>
                         </tr>
                     </tbody>
                 </table>
             </div>
         </div>
     </div>
     <input id="hdbase" type="hidden" value="@ViewBag.baseId"/>
     <input id="hdtr" type="hidden" value="@ViewBag.Tr"/>
     <input id="hddiv" type="hidden" value="@ViewBag.div"/>
     <input id="hdall" type="hidden" value="@ViewBag.AllData"/>
     <script type="text/javascript">
         $(document).ready(function () {
             window.onload = function () {
                 if ($("#hdall").val() != "") {
                     $("#main").html($("#hdall").val());
                 }
                 ///初始化给div加移动事件
                 $("#main").find("span.title").each(function () {
                     this.onmousedown = MoveBegin;
                 });
                 ///给+TD事件
                 $("#main").find("td.jiatr").each(function () {
                     $(this).click(TdClick);
                     $(this).attr("title", "新增一行");
                 });
                 ///添加DIV按钮
                 $("#addTable").click(AddTbale);
                 $("#getData").click(GetData);
                 $("#saveData").click(SaveData);
                 ///给select绑定事件
                 $("#main").find("div.tbbox").each(function () {
                     SortList(this);
                     $(this).find("span.spright").click(DelDiv);
                 });
                 CheckMainHeight();
             }
             ///返回txt文件
             function SaveTxt(arr) {
                 var loogParam = arr;
                 var nwin = window.open('/home/DataText?t=' + Math.random(), 'newwindow', 'height=5, width=5, top=400,left=500, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no');
                 document.body.insertAdjacentHTML("beforeEnd", "<form  name='form1'  action='/home/DataText'  target='newpage'  method='post'><input  type='hidden'  name='param'></form>");
                 document.form1.param.value = loogParam;
                 document.form1.submit();
                 $("form").remove();
                 nwin.close();
             }
             ///txt文件空格占位
             function NullSpace(defnum, str) {
                 var s = "\040";
                 var r = "";
                 var l = str.length;
                 var num = defnum - l;
                 for (var i = 0; i < num; i++) {
                     r += s;
                 }
                 return r;
             }
             ///"-"占位符
             function NullH(defnum, str) {
                 var s = "-";
                 var r = "";
                 var l = str.length;
                 var num = defnum - l;
                 for (var i = 0; i < num; i++) {
                     r += s;
                 }
                 return r;
             }
             ///下载脚本为txt文件
             function GetData() {
                 var tbName = "";
                 var tr = 0;
                 var sav = true;
                 var br = "\r\n";
                 var strSql = "use  " + $("#txtBaseName").val() + br;
                 $("#main").find("div.tbbox").each(function () {
                     tbName = $($(this).find(".tbname")[1]).val();
                     var desName = $($(this).find(".tbname")[0]).val();
                     var sqlExists = "if exists ( select *  from  sysobjects where name = '" + tbName + "' and xtype='U') " + br + ""
                                 + "drop table " + tbName + "";
                     strSql += sqlExists + br;
                     strSql += "create table  " + tbName + NullH(67, tbName) + desName + br + "(" + br;
                     $(this).find("tr").each(function (index, element) {
                         if (index > 0) {
                             var tdlist = $(this).find("td");
                             var key = $(tdlist[0]).find("input").val();
                             if ($.trim(key) != "") {
                                 if (key.length >= 17) {
                                     alert(key + "超出了15个字符的限制");
                                     //alert(strSql);
                                     sav = false;
                                     return;
                                 }
                                 key += NullSpace(17, key);
                                 var col = $(tdlist[1]).find("input").val();
                                 col += NullSpace(17, col);
                                 if (index == 1)
                                     col = "int" + NullSpace(17, "int");
                                 var def = $(tdlist[2]).find("input").val() == "" ? "default ''" : "default  " + $(tdlist[2]).find("input").val();
                                 def += NullSpace(32, def);
                                 if (index == 1)
                                     def = "primary key identity(1,1)" + NullSpace(32, "primary key identity(1,1)");
                                 var des = "--" + $(tdlist[3]).find("input").val();
                                 if (index == 1)
                                     des = "--主键-" + $(tdlist[3]).find("input").val();
                                 strSql += "\040\040" + key + col + def + "NOT NULL , " + des + br;
                                 tr++;
                             }
                         }
                     });
                     strSql += ");" + br + br + br;
                 });
                 if (sav && tr > 0) {
                     $("#saveData").click();
                     SaveTxt(strSql);
                 }
             }
             ///给数据类型列加事件
             function SortList(obj) {
                 $(obj).find("div.sortdiv").each(function () {
                     $(this).find("select:first").change(ChangeVal).change(DefaultTxt);
                     $(this).find("input:first").focus(ShowSel);
                     $(this.parentNode).mouseenter(ShowSel).mouseleave(HideSel);
                     $(this.parentNode.parentNode).find(".txtdef").blur(DefaultTxt);
                 });
             }
             ///删除div
             function DelDiv() {
                 $(this.parentNode.parentNode).remove();
             }
             ///改变数据类型
             function ChangeVal(obj) {
                 $(this.parentNode.parentNode).find(".sortinput").val($(this.parentNode).find(".selsort").val());
             }
             ///默认值
             function DefaultTxt(obj) {
                 var txt = $(this.parentNode.parentNode).find(".txtdef:first")[0];
                 if (obj.type == "change") {
                     txt = $(this.parentNode.parentNode.parentNode.parentNode).find(".txtdef:first")[0];
                 }
                 var val = $(txt).val().replace("'", "").replace("'", "");
                 $(txt).val(val);
                 if ($.trim($(txt).val()) != "" && $.trim($(txt).val().toLowerCase()) != "getdate()" && $.trim($(txt.parentNode.parentNode).find(".sortinput").val()) != "int" && $.trim($(txt.parentNode.parentNode).find(".sortinput").val()) != "float") {
                     $(txt).val("'" + val + "'");
                 }
             }
             ///数据类型下拉显示
             function ShowSel(obj) {
                 $(this.parentNode).find(".selspan").show();
                 $(this.parentNode).find(".sortinput").width("90px");
                 $(this.parentNode).find(".sortinput").css("position", "absolute");
             }
             ///数据类型下拉隐藏
             function HideSel(obj) {
                 var td = this;
                 var o = obj.relatedTarget || obj.toElement;
                 if (!o) {
                     return;
                 }
                 $(td).find(".selspan").hide();
                 $(td).find(".sortinput").width("118px");
                 $(td).find(".sortinput").css("position", "");
             }
             ///添加DIV
             function AddTbale() {
                 var child = document.createElement("div");
                 child.className = "tbbox";
                 var name = Math.random().toString().substr(2, 3);
                 var div = $("#hddiv").val().replace("tb_Name", "tb_" + name);
                 $(child).html(div);
                 $(child).find("span.title").each(function () {
                     this.onmousedown = MoveBegin;
                 });
                 $(child).find("span.spright").click(DelDiv);
                 $(child).find("td.jiatr").each(function () {
                     $(this).click(TdClick);
                     $(this).attr("title", "新增一行");
                 });
                 SortList(child);
                 $("#main").append(child);
                 CheckMainHeight();
             }
             ///TD增加一行点击
             function TdClick(obj) {
                 var tooltipem = $(this.parentNode).find("td:first").find("input:first");
                 if ($.trim(tooltipem.val()) == "") {
                     $(tooltipem).tooltip({
                         "title": "这里还没填写呢~!",
                         "trigger": "manual",
                         "placement": "right",
                         "delay": 800
                     });
                     $(tooltipem).tooltip("show");
                     $(tooltipem).focus();
                     setTimeout(function () { $(tooltipem).tooltip("hide"); }, 1800)
                     return false;
                 }
                 $(tooltipem).tooltip("destroy");
                 var tr = $("#hdtr").val();
                 var child = document.createElement("tr");
                 $(child).html(tr);
                 $(this.parentNode.parentNode).append(child);
                 SortList(child);
                 $(child).find("td.jiatr").click(TdClick);
                 $(this).removeClass();
                 $(this).unbind();
                 $(this).html("");
                 $(this).attr("title", "");
                 CheckMainHeight();
                 $($($(this.parentNode.parentNode).find("tr:first").next("tr"))).find("td:last").addClass("prmkey").attr("title", "第一行默认为主键&自增长");
             }
             ///校验div#main高度
             function CheckMainHeight() {
                 $("#main").find("div").each(function () {
                     if (this.offsetTop + $(this).height() > $("#main").height())
                         $("#main").height(this.offsetTop + $(this).height() + 10);
                 });
             }
             ///移动
             function MoveBegin(obj) {
                 var e = obj || window.event,
                 x1 = e.clientX;
                 y1 = e.clientY;
                 var setOn = this.parentNode.parentNode;
                 var defLeft = setOn.offsetLeft;
                 var defTop = setOn.offsetTop;
                 document.onmousemove = function (event) {
                     var e = event || window.event;
                     //
                     x2 = e.clientX;
                     y2 = e.clientY;
                     //
                     x = x2 - x1;
                     y = y2 - y1;
                     var setLeft = defLeft + x;
                     var setTop = defTop + y;
                     setOn.style.position = "absolute";
                     //setOn.style.filter = 'alpha(opacity=80)';
                     //setOn.style.opacity = "0.8";
                     if (setLeft <= 0) {
                         setLeft = 0;
                     }
                     if (setTop <= 0) {
                         setTop = 0;
                     }
                     if (setLeft >= $("#main").width() - $(setOn).width() - 9) {
                         setLeft = $("#main").width() - $(setOn).width() - 14;
                     }
                     if (setTop > $("#main").height() - $(setOn).height() + 10) {
                         $("#main").height(setTop + $(setOn).height() + 100);
                         setTop = $("#main").height() - $(setOn).height();
                     }
                     setOn.style.left = setLeft + 'px';
                     setOn.style.top = setTop + 'px';
                     //$("#showText").text("Top:" + setOn.style.top + "; Left:" + setOn.style.left + "; OFl:" + "");
                 }
                 document.onmouseup = function () {
                     this.onmousemove = null;
                 }
             }
         });
     </script>
里面有JS拖拽代码, 都很简单, 上面这些是我2年前做的东西,很多命名之类的都不规范,大家关注方法就好。
后台代码:
public ActionResult Index()
{
StringBuilder sb = new StringBuilder(); sb.Append("<td>");
sb.Append("<input type=\"text\" />");
sb.Append("</td>");
sb.Append("<td>");
sb.Append("<div class=\"sortdiv\">");
sb.Append("<span class=\"selspan\">");
sb.Append("<select class=\"selsort\">");
sb.Append("<option value=\"int\">int</option>");
sb.Append("<option value=\"varchar(50)\">varchar(50)</option>");
sb.Append(" <option value=\"nvarchar(200)\">nvarchar(200)</option>");
sb.Append("<option value=\"datetime\">datetime</option>");
sb.Append("<option value=\"float\">float</option>");
sb.Append("<option value=\"text\">text</option>");
sb.Append("<option value=\"ntext\">ntext</option>");
sb.Append("</select>");
sb.Append("</span>");
sb.Append("<input value=\"int\" class=\"sortinput\" />");
sb.Append("</div>");
sb.Append("</td>");
sb.Append("<td>");
sb.Append("<input class=\"txtdef\" type=\"text\" />");
sb.Append("</td>");
sb.Append("<td>");
sb.Append("<input type=\"text\" />");
sb.Append("</td>");
sb.Append("<td id=\"tool\" class=\"jiatr\" title=\"新增一行\" style=\"border: 0\">");
sb.Append("+");
sb.Append("</td>");
ViewBag.Tr = sb.ToString(); StringBuilder sbdiv = new StringBuilder();
sbdiv.Append("<div class='titletr' title=''>");
sbdiv.Append("<span class='spleft'>");
sbdiv.Append("<input value='XXX表' class='tbname' type='text' />");
sbdiv.Append("</span>");
sbdiv.Append("<span class='title'></span>");
sbdiv.Append("<span class='spright'></span>");
sbdiv.Append("</div>");
sbdiv.Append("<div class='titletr' title=''>");
sbdiv.Append("<span class='spleft'>");
sbdiv.Append("名:<input value='tb_Name' class='tbname' type='text' />");
sbdiv.Append("</span>");
sbdiv.Append("<span class='title'></span>");
sbdiv.Append("<span class='spright'>删除</span>");
sbdiv.Append("</div>");
sbdiv.Append("<table class='tablelist'>");
sbdiv.Append("<tbody>");
sbdiv.Append("<tr>");
sbdiv.Append("<td>");
sbdiv.Append("字段名");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append("类型");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append("默认值");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append(" 备注");
sbdiv.Append("</td>");
sbdiv.Append("<td style='border: 0'>");
sbdiv.Append("</td>");
sbdiv.Append("</tr>");
sbdiv.Append("<tr>");
sbdiv.Append("<td>");
sbdiv.Append("<input type='text' />");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append("<div class='sortdiv'>");
sbdiv.Append("<span class='selspan'>");
sbdiv.Append("<select class='selsort'>");
sbdiv.Append("<option value='int'>int</option>");
sbdiv.Append("<option value='varchar(50)'>varchar(50)</option>");
sbdiv.Append("<option value='nvarchar(200)'>nvarchar(200)</option>");
sbdiv.Append("<option value='datetime'>datetime</option>");
sbdiv.Append("<option value='float'>float</option>");
sbdiv.Append("<option value='text'>text</option>");
sbdiv.Append("<option value='ntext'>ntext</option>");
sbdiv.Append("</select>");
sbdiv.Append("</span>");
sbdiv.Append("<input value='int' class='sortinput' />");
sbdiv.Append("</div>");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append("<input class='txtdef' type='text' />");
sbdiv.Append("</td>");
sbdiv.Append("<td>");
sbdiv.Append("<input type='text' />");
sbdiv.Append("</td>");
sbdiv.Append("<td id='tool' class='jiatr' style='border: 0'>");
sbdiv.Append(" +");
sbdiv.Append("</td>");
sbdiv.Append("</tr>");
sbdiv.Append("</tbody>");
sbdiv.Append("</table>");
ViewBag.div = sbdiv.ToString();
ViewBag.AllData = "";
ViewBag.baseId = "";
ViewBag.baseName = "basename";
ViewBag.baseDes = "备注说明"; return View(); }
//响应下载脚本请求,返回txt文件
public void DataText()
{
if (Request["param"] == null)
return;
string t = Request["param"];
if (t == "")
return;
string tbName = "数据库-" + System.DateTime.Now.ToString("yyMMdd-HHmmss")+".sql";
Response.AppendHeader("Content-Disposition", "attachment;filename=" + tbName);
Response.ContentEncoding = System.Text.Encoding.Default;
Response.ContentType = "text/plain";
Response.Write(t);
}
在线暂时测试地址:http://websql.puworld.com
工欲善其事必先利其器---SQL在线可视化模型设计,(还可学习拖拽知识)的更多相关文章
- h5页面ios,双击向上滑动,拖拽到底部还能继续拖拽(露出黑色背景)
		
h5页面ios,双击向上滑动,拖拽到底部还能继续拖拽 标签: 手机 2016-02-02 18:09 696人阅读 评论(0) 收藏 举报 在ios下,双击屏幕某些地方,滚动条会自动向上走一段. ...
 - 古语云:工欲善其事必先利其器 --> 最新、最全的 IntelliJ IDEA(2018.3.3)  的介绍、安装、破解、配置与使用
		
原文:古语云:工欲善其事必先利其器 --> 最新.最全的 IntelliJ IDEA(2018.3.3) 的介绍.安装.破解.配置与使用 一.IntelliJ IDEA 介绍 -> Ecl ...
 - TIZ_c 第0周总结(2019/10/15-2019/10/22)工欲善其事必先利其器
		
TIZ_c 第0周总结(2019/10/15-2019/10/22)工欲善其事必先利其器 任务清单 给自己取一个酷酷的id,并选择1-2个喜欢的方向.(只是初步选择,后期可更改) 改下群名片.例如yo ...
 - 转:【工欲善其事必先利其器】—Entity Framework实例详解
		
开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/ ...
 - 单片机开发——02工欲善其事必先利其器(Proteus软件安装破解)
		
在单片机开发工程中,博主经常通过模拟软件Proteus进行模拟仿真,将编译生成的"HEX"文件下载在单片机芯片中,然后进行后期的debug工作,当模拟仿真完成之后,进行硬件测试部分 ...
 - 单片机开发——01工欲善其事必先利其器(Keil软件安装破解)
		
本文是博主<单片机开发>博客第一篇文章,主要讲述51单片机编程软件Keil uVision4的安装及破解过程. 1. Keil uVision4安装包文件 PATH:链接 ...
 - yaml语言在线可视化翻译
		
yaml语言在线可视化翻译 https://editor.swagger.io/
 - [sql Server]除非另外还指定了TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
		
今天遇到一个奇怪的问题,项目突然要从mysql切换到sql server数据库,包含order by 子句的嵌套子查询报错. 示例:select top 10 name,age,sex from ( ...
 - 工欲善其事必先利其器--------搭建Android平台
		
工欲善其事必先利其器--------搭建Android平台 1.1 安装JDK 在Eclipse的开发过程中需要JDK或JRE的支持,否则会报错. (1) 下载JDK(建 ...
 
随机推荐
- centos上如何安装mysql
			
centos可以使用yum安装mysql 但是版本很低,且不灵活. 本文将介绍如何使用安装包安装mysql http://dev.mysql.com/downloads/mysql/ 下载mysql ...
 - debian系(Ubuntu)安装jenkins(持续集成)
			
wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - sudo sh -c 'ec ...
 - Playground
			
题意 :求被两点分割的凸包面积的较小值 题意已经给出顺时针啦 就是求以某一个点 和其他所有相邻点组成三角形的面积,然后sum存和求两点的时候就求出那两点的之间所有三角形的和再减掉0点和那两点的面 ...
 - poj3254状压DP入门
			
G - 状压dp Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:65536KB 64bit ...
 - C/C++中new关键字是否加括号的区别
			
代码: #include <iostream> using namespace std; class A{ public: int a; }; int main(){ A *a1 = ne ...
 - 线段树:Segment Tree(单点修改/区间修改模板) C++
			
线段树是非常有效的数据结构,可以快速的维护单点修改,区域修改,查询最大值,最小值等功能. 同时,它也很重要.如果有一天比赛,你卡在了一道线段树模板题目上,这就真的尴尬了.不过,随着时代的进步,题目也越 ...
 - Js判断来访问者的系统
			
var ua = navigator.userAgent; ) { alert('您使用的是win32 XP系统!'); } else { alert('您使用的是Win7系统!'); }
 - C语言初学 求100到200的全部素数
			
#include<stdio.h> #include<math.h> int main() { int m,i,k; for(m=101;m<=200;m=m+2) { ...
 - 转载的别人的ajax跨域解决方法
			
http://dynamic.vip.xxxxxx.com/active/<controllers>/<active>/<id> 放在浏览器地址栏中访问可以得到正确 ...
 - 转:Qt 嵌入式开发环境搭建
			
地址: http://www.cnblogs.com/lishixian/articles/3013897.html 作者:lsx_007 这里主要是记录了自己在搭建嵌入式开发环境时阅 ...