精华内容
下载资源
问答
  • GSON解析json存在不确定实体

    千次阅读 2017-12-19 23:15:08
    这几天遇到个解析json的问题,返回的json数据包含不同的实体类,实体类的键值是确定的但是类型是不确定的。(描述可能不对,下面给出json例子) json数据例子如下: String dataA = "{a:1, b:'Hello,world!', c:...

    这几天遇到个解析json的问题,返回的json数据中包含不同的实体类,实体类的键值是确定的但是类型是不确定的。(尴尬描述可能不对,下面给出json例子)

    json数据例子如下:
    String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
    String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";
    String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";

    网上找了很久,首先找到定义d为泛型,然后用JSONObject  jsond = new JSONObject(String arg0)的方法得到d的json数据,最后用D d =  gson.fromJson( jsond.toString(), D.class)解析出具体的实体类。下面看一下具体的实现。

    Entity.java

    public class Entity {
    	private int a;
    	private String b;
    	private boolean c;
    	private Object d;
    	public int getA() {
    		return a;
    	}
    	public void setA(int a) {
    		this.a = a;
    	}
    	public String getB() {
    		return b;
    	}
    	public void setB(String b) {
    		this.b = b;
    	}
    	public boolean isC() {
    		return c;
    	}
    	public void setC(boolean c) {
    		this.c = c;
    	}
    	public Object getD() {
    		return d;
    	}
    	public void setD(Object d) {
    		this.d = d;
    	}
    	@Override
    	public String toString() {
    		return "Entity [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";
    	}
    }
    DA.java

    public class DA {
    	private int aa;
    	public int getAa() {
    		return aa;
    	}
    	public void setAa(int aa) {
    		this.aa = aa;
    	}
    	@Override
    	public String toString() {
    		return "DA [aa=" + aa + "]";
    	}
    }

    DB.java

    public class DB {
    	private int ba;
    	private String bb;
    	public int getBa() {
    		return ba;
    	}
    	public void setBa(int ba) {
    		this.ba = ba;
    	}
    	public String getBb() {
    		return bb;
    	}
    	public void setBb(String bb) {
    		this.bb = bb;
    	}
    	@Override
    	public String toString() {
    		return "DB [ba=" + ba + ", bb=" + bb + "]";
    	}
    }

    DC.java

    public class DC {
    	private int ca;
    	private String cb;
    	private boolean cc;
    	public DC(int ca, String cb, boolean cc) {
    		super();
    		this.ca = ca;
    		this.cb = cb;
    		this.cc = cc;
    	}
    	public int getCa() {
    		return ca;
    	}
    	public void setCa(int ca) {
    		this.ca = ca;
    	}
    	public String getCb() {
    		return cb;
    	}
    	public void setCb(String cb) {
    		this.cb = cb;
    	}
    	public boolean isCc() {
    		return cc;
    	}
    	public void setCc(boolean cc) {
    		this.cc = cc;
    	}
    	@Override
    	public String toString() {
    		return "DC [ca=" + ca + ", cb=" + cb + ", cc=" + cc + "]";
    	}
    }
    jsontest.java

    import com.google.gson.Gson;
    import com.mathworks.toolbox.javabuilder.external.org.json.JSONObject;
    
    public class jsontest {
    	public static void main(String[] args) {
    		String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
    		String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";
    		String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";
    	    Gson gson = new Gson();  
    	    Entity ea = gson.fromJson(dataA, Entity.class);
    	    Entity eb = gson.fromJson(dataB, Entity.class);
    	    Entity ec = gson.fromJson(dataC, Entity.class);
    
    	    System.out.println("ea ="+ea.toString());
    	    System.out.println("eb ="+eb.toString());
    	    System.out.println("ec ="+ec.toString());
    
    	    ea = gson.fromJson(dataA, Entity.class);
    	    eb = gson.fromJson(dataB, Entity.class);
    	    ec = gson.fromJson(dataC, Entity.class);
    	    if(ea.getA()==1){
    		    System.out.println("ea.getD() ="+ea.getD().toString());
    	    	try {
    				JSONObject d = new JSONObject(ea.getD().toString());
    			    System.out.println("d ="+d.toString());
    		    	DA da =  gson.fromJson(d.toString(), DA.class);
    			    System.out.println("da ="+da.toString());
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    	    }
    	    System.out.println("");
    	    if(eb.getA()==2){
    		    System.out.println("eb.getD() ="+eb.getD().toString());
    	    	try {
    				JSONObject d = new JSONObject(eb.getD().toString());
    			    System.out.println("d ="+d.toString());
    		    	DB db =  gson.fromJson(d.toString(), DB.class);
    			    System.out.println("db ="+db.toString());
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    	    }
    	    System.out.println("");
    	    if(ec.getA()==3){
    		    System.out.println("ec.getD() ="+ec.getD().toString());
    	    	try {
    				JSONObject d = new JSONObject(ec.getD().toString());
    			    System.out.println("d ="+d.toString());
    		    	DC dc =  gson.fromJson(d.toString(), DC.class);
    			    System.out.println("dc ="+dc.toString());
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    	    }
    	}
    }
    运行结果:

    ea =Entity [a=1, b=Hello,world!, c=true, d={aa=1.0}]
    eb =Entity [a=2, b=Hello,world!, c=true, d={ba=1.0, bb=Hello word!}]
    ec =Entity [a=3, b=Hello,world!, c=true, d={ca=1.0, cb=Hello,:world!, cc=true}]
    ea.getD() ={aa=1.0}
    d ={"aa":1}
    da =DA [aa=1]
    
    eb.getD() ={ba=1.0, bb=Hello word!}
    d ={"bb":"Hello word!","ba":1}
    db =DB [ba=1, bb=Hello word!]
    
    ec.getD() ={ca=1.0, cb=Hello,:world!, cc=true}
    com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Missing value at character 18 of {ca=1.0, cb=Hello,:world!, cc=true}
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.nextValue(JSONTokener.java:349)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:191)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)
    	at com.example.json.jsontest.main(jsontest.java:51)


    当字符串中包含,:等特殊符号时不能正确解析。原因是形如{ca=1.0, cb=Hello,:world!, cc=true}的字符串不能转换为json数据。

    当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";
    报错
    com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Expected a ':' after a key at character 25 of {ca=1.0, cb=Hello,world!, cc=true}at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:204)at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)at com.example.json.jsontest.main(jsontest.java:51)
    
    

    
    
    当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello:world!', cc:true}}";
    报错
    com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Expected a ',' or '}' at character 18 of {ca=1.0, cb=Hello:world!, cc=true}
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:223)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)
    	at com.example.json.jsontest.main(jsontest.java:51)
    当dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,:world!', cc:true}}";
    报错
    com.mathworks.toolbox.javabuilder.external.org.json.JSONException: Missing value at character 18 of {ca=1.0, cb=Hello,:world!, cc=true}
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.syntaxError(JSONTokener.java:451)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONTokener.nextValue(JSONTokener.java:349)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:191)
    	at com.mathworks.toolbox.javabuilder.external.org.json.JSONObject.<init>(JSONObject.java:327)
    	at com.example.json.jsontest.main(jsontest.java:51)
    如果收到的json数据是dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:\'\"Hello,world!\"\', cc:true}}";则可以解析,因为第一次解析得到的是{ca=1.0, cb="Hello,world!", cc=true},可以转换成json数据,但是别人不可能按我的需求这样发给我。可怜

    然后在网上继续找字符串转换为实体类,发现很多人说啥反射工厂模式,觉得意思就和编译原理里的词法分析、语法分析差不多,就是一个一个地进行匹配,然后我就像下面这样做。

    jsonsubtest.java

    import com.google.gson.Gson;
    
    public class jsonsubtest {
    	public static void main(String[] args) {
    		String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
    		String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";
    		String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";
    	    Gson gson = new Gson();  
    	    DC dctest = new DC(1, null, false);
    	    String jsondctest = gson.toJson(dctest, DC.class);
    	    System.out.println("jsondctest ="+jsondctest);
    	    
    	    Entity ea = gson.fromJson(dataA, Entity.class);
    	    Entity eb = gson.fromJson(dataB, Entity.class);
    	    Entity ec = gson.fromJson(dataC, Entity.class);
    
    	    System.out.println("ea ="+ea.toString());
    	    System.out.println("eb ="+eb.toString());
    	    System.out.println("ec ="+ec.toString());
    
    	    DC dc1 = getD(ec.getD().toString());
    	    System.out.println("dc1 ="+dc1.toString());
    	    DC dc2 = getD("{ca=1.0, cc=true}");
    	    System.out.println("dc2 ="+dc2.toString());
    	    DC dc3 = getD("{ca=1.0, cb=Hello,cc=world!, cc=true}");
    	    System.out.println("dc3 ="+dc3.toString());
    	    DC dc4 = getDcut("{ca=1.0, cb=Hello,cc=world!, cc=true}");
    	    System.out.println("dc4 ="+dc4.toString());
    	    DC dc5 = getDcut("{ca=1.0, cb=Hello, cc=world!, cc=true}");
    	    System.out.println("dc5 ="+dc5.toString());
    	}
    	public static DC getD(String srcstr) {//{ca=1.0, cb=Hello,world!, cc=true} {ca=1.0, cc=true}
    		int a = 0;
    		String b = null;
    		boolean c = false;
    		String temp = "";
    		int start,end = 0;
    		start = srcstr.indexOf("ca=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf(", ");
    			if(end!=-1)
    				a = (int) Float.parseFloat(temp.substring(3, end));
    		}
    		start = srcstr.indexOf("cb=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf(", cc");
    			if(end!=-1)
    				b = temp.substring(3, end);
    		}
    		start = srcstr.indexOf("cc=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf("}");
    			if(end!=-1)
    				c = Boolean.parseBoolean(temp.substring(3, end));
    		}
    		DC dc = new DC(a, b, c);
    		return dc;
    	}
    	private static DC getDcut(String srcstr) {
    		int a = 0;
    		String b = null;
    		boolean c = false;
    		String temp = "";
    		int start,end = 0;
    	    System.out.println("srcstr1 ="+srcstr);
    		start = srcstr.indexOf("ca=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf(", ");
    			if(end!=-1)
    				a = (int) Float.parseFloat(temp.substring(3, end));
    		}
    		if(start!=-1 && end!=-1){
    			temp = srcstr.substring(start, end+2);
    			srcstr = srcstr.replace(temp, "");
    		}
    	    System.out.println("srcstr2 ="+srcstr);
    		start = srcstr.indexOf("cb=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf(", cc");
    			if(end!=-1)
    				b = temp.substring(3, end);
    		}
    		if(start!=-1 && end!=-1){
    			temp = srcstr.substring(start, end+4);
    			srcstr = srcstr.replace(temp, "");
    		}
    	    System.out.println("srcstr3 ="+srcstr);
    		start = srcstr.indexOf("cc=");
    		if(start!=-1){
    			temp = srcstr.substring(start);
    			end = temp.indexOf("}");
    			if(end!=-1)
    				c = Boolean.parseBoolean(temp.substring(3, end));
    		}
    		DC dc = new DC(a, b, c);
    		return dc;
    	}
    }
    运行结果:

    jsondctest ={"ca":1,"cc":false}
    ea =Entity [a=1, b=Hello,world!, c=true, d={aa=1.0}]
    eb =Entity [a=2, b=Hello,world!, c=true, d={ba=1.0, bb=Hello word!}]
    ec =Entity [a=3, b=Hello,world!, c=true, d={ca=1.0, cb=Hello,world!, cc=true}]
    dc1 =DC [ca=1, cb=Hello,world!, cc=true]
    dc2 =DC [ca=1, cb=null, cc=true]
    dc3 =DC [ca=1, cb=Hello,cc=world!, cc=false]
    srcstr1 ={ca=1.0, cb=Hello,cc=world!, cc=true}
    srcstr2 ={ cb=Hello,cc=world!, cc=true}
    srcstr3 ={ cc=true}
    dc4 =DC [ca=1, cb=Hello,cc=world!, cc=true]
    srcstr1 ={ca=1.0, cb=Hello, cc=world!, cc=true}
    srcstr2 ={ cb=Hello, cc=world!, cc=true}
    srcstr3 ={ cc=world!, cc=true}
    dc5 =DC [ca=1, cb=Hello, cc=false]
    尴尬结果真是不忍直视。

    后来在http://blog.csdn.net/yuanguozhengjust/article/details/50477128才发现可以这样做。

    EntityT.java

    public class EntityT <T>{
    	private int a;
    	private String b;
    	private boolean c;
    	private T d;
    	public int getA() {
    		return a;
    	}
    	public void setA(int a) {
    		this.a = a;
    	}
    	public String getB() {
    		return b;
    	}
    	public void setB(String b) {
    		this.b = b;
    	}
    	public boolean isC() {
    		return c;
    	}
    	public void setC(boolean c) {
    		this.c = c;
    	}
    	public T getD() {
    		return d;
    	}
    	public void setD(T d) {
    		this.d = d;
    	}
    	@Override
    	public String toString() {
    		return "EntityT [a=" + a + ", b=" + b + ", c=" + c + ", d=" + d + "]";
    	}
    }
    jsonentitytest.java

    import java.lang.reflect.Type;
    import com.google.gson.Gson;
    import com.google.gson.reflect.TypeToken;
    
    public class jsonentitytest {
    	public static void main(String[] args) {
    		String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
    		String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:'Hello word!'}}";
    		String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:'Hello,world!', cc:true}}";
    //		String dataA = "{a:1, b:'Hello,world!', c:true, d:{aa:1}}";
    //		String dataB = "{a:2, b:'Hello,world!', c:true, d:{ba:1, bb:\'\"Hello,word!\"\'}}";
    //		String dataC = "{a:3, b:'Hello,world!', c:true, d:{ca:1, cb:\'\"Hello,world!\"\', cc:true}}";
    //		String dataA = "{\"a\":1, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"aa\":1}}";
    //		String dataB = "{\"a\":2, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"ba\":1, \"bb\":\'\"Hello,world!\"\'}}";
    //		String dataC = "{\"a\":3, \"b\":\"Hello,world!\", \"c\":true, \"d\":{\"ca\":1, \"cb\":\'Hello,world!\', \"cc\":true}}";
    	    Gson gson = new Gson();  
    	    
    	    DC dctest = new DC(1, null, false);
    	    String jsondctest = gson.toJson(dctest, DC.class);
    	    System.out.println("jsondctest ="+jsondctest);
    	    
    	    EntityT ea = gson.fromJson(dataA, EntityT.class);
    	    EntityT eb = gson.fromJson(dataB, EntityT.class);
    	    EntityT ec = gson.fromJson(dataC, EntityT.class);
    
    	    System.out.println("ea ="+ea.toString());
    	    System.out.println("eb ="+eb.toString());
    	    System.out.println("ec ="+ec.toString());
    
    	    System.out.println("");
    	    if(ea.getA()==1){
    	        Type jsonType = new TypeToken<EntityT<DA>>() {}.getType();  
    	    	ea = gson.fromJson(dataA, jsonType); 
    		    System.out.println("ea ="+ea.toString());
    	    }
    	    if(eb.getA()==2){
    	        Type jsonType = new TypeToken<EntityT<DB>>() {}.getType();  
    	    	eb = gson.fromJson(dataB, jsonType); 
    		    System.out.println("eb ="+eb.toString());
    	    }
    	    if(ec.getA()==3){
    	        Type jsonType = new TypeToken<EntityT<DC>>() {}.getType();  
    	    	ec = gson.fromJson(dataC, jsonType); 
    		    System.out.println("ec ="+ec.toString());
    	    }
    	}
    }
    

    至此已经能满足我的需求了,也没精神再找新方法了,睡觉睡觉

    本文链接http://blog.csdn.net/qq_25189723/article/details/78848521

    展开全文
  • 目录写最前一、 强实体与弱实体的定义1. 强实体2. 弱实体百度百科的解释《数据库系统课程》的解释总结起来 写最前 数据库设计是困难的,其原因之一就在于我们很难去完全把握实体的定义。是不是实体、该不该...

    写在最前

    数据库设计是困难的,其原因之一就在于我们很难去完全把握实体的定义。是不是实体、该不该定义实体是一直困扰数据库初学者的问题,强实体、弱实体的概念同样难以理解。
    我一直深受强实体、弱实体概念的困扰,百度百科中的定义不能很好地解决我的困惑,一路学习过来,自己对强实体、弱实体的理解越来越深入,因此写下这篇文章与大家分享自己对强实体与弱实体的一些体会。如果觉得有帮助,请点赞鼓励!

    一、 强实体与弱实体的定义

    1. 强实体

    其实例的存在不依赖于任何其他实体类型的实例;有自己独立的主键,唯一性地标识它的每个实例。

    2. 弱实体

    百度百科中的解释

    一个实体对于另一个实体(一般为强实体,也可以是依赖于其他强实体的弱实体)具有很强的依赖联系,而且该实体主键的一部分或全部从其强实体(或者对应的弱实体依赖的强实体)中获得,则称该实体为弱实体。

    《数据库系统课程》中的解释

    其实例的存在依赖于其它实体类型的实例;其主键包括它所依赖的实体类型的主键。

    总结起来

    百度百科中的解释和课程中的解释都是在强调两点:
    第一点:依赖,弱实体应该依赖于强实体;
    第二点:主键,弱实体的主键应该是组合主键(其他实体的主键组成的)。

    二、 关于定义的几个疑惑

    但定义中有几个地方令我不解,我相信初学者多少也会遇到同样的问题。我总结了四点:

    什么叫“依赖”?

    以教务系统数据库为例,如果没有学校,那么学院不再是学院,学生不再是学生,课程更将不复存在,所以这些实体都依赖于其他实体,因此这些都是弱实体?但我们知道,学院、学生一般都作为强实体。因此,定义中的“依赖”指的是什么呢?

    先有鸡还是先有蛋?

    是因为一个实体的主键包括其他实体的主键而使该实体成为了弱实体,还是因为一个实体是弱实体,所以它的主键必须包括其他实体的主键?
    这是一个先鸡(弱实体)还是先蛋(组合主键)的问题。

    为什么要定义弱实体?

    我们知道,弱实体对于另一个实体具有很强的依赖联系,似乎并不是“真实”存在的事物,那么为什么我们还会有弱实体的概念,而不是直接认为实体就是强实体呢?

    什么时候需要定义弱实体?

    有时候弱实体就是需求中的实体,只是它依赖于其他实体,有时候关系也可以认为是弱实体,有时候出于设计的需要我们也会定义弱实体,那么何时需要定义弱实体?

    总结起来,以上四个问题其实是一个问题:

    怎样正确地理解强实体与弱实体的含义?

    三、 唯有实践,方出真知

    有很多事情是很难想明白的,但经过几次数据库设计实战,我发现自己或多或少地定义了一些弱实体。我选取了三个典型的例子:

    教务系统数据库设计(一)

    之后我会专门写一篇博客介绍教务系统数据库的设计过程,这里选取其中一个比较典型的部分。业务需求是这样的:

    一周有七天,每一天有11节。

    上面这句话中涉及到了几个实体?很简单吧,三个实体:周、天、节。那么它们是强实体还是弱实体呢?不好说,但是我们可以确定,概念数据模型的设计应该是这个样子:
    在这里插入图片描述
    需要勾选“Dependent”。首先回答一个问题:为什么不能是下面这个样子?
    在这里插入图片描述
    Day的主键应该是dayOfWeek,如果不用“Dependent”将Day的主键改为weekNum+dayOfWeek,我们的Day表格中只能有七行记录,也就是说对于某一个星期一,我们无法区分这是第几周的星期一!同样的道理,如果Section的主键仅仅为sectionNum,那么我们根本无法区分这一节课是哪一天的课!教务系统要有排课、选课功能,只知道第1节,但不知道是哪一天的第一节,这肯定是不可以的。

    因此,当我们想要找到某一节时,需要同时指定那一周、星期几、哪一节。比方说我可以把《数据库设计》这门课安排在第一周星期一三四节。

    在这个例子中,三个实体都是需求中明明白白告诉我们的实体,但我们将Day与Section都作为了弱实体,因为强实体的Day与Section根本无法满足需求。

    培训公司数据库设计

    业务需求是这样的:

    每位学生每期只能参加一门课程。

    言外之意,公司有很多课程。我们只分析“每位学生每期只能参加一门课程”这一需求,发现涉及到两个实体:学生、课程。所以我们或许会想当然地这样去设计数据库:
    在这里插入图片描述
    一个课程可以由多个学生选择,一个学生只可以选择一门课程。发现问题了吗?业务需求里不是说一个学生只能参加一门课程,而是说一个学生在一期只能参加一门课程!这么设计数据库是在断人家财路。因此,我们必须考虑“每期课程”这个概念:在这里插入图片描述
    看样子似乎是没问题了,但是数据库设计是不可能这么容易就没问题的。我们把每期课程都作为一个记录,那么对于课程的信息,比方说课程名称、价格、介绍,每开一期课就要向数据库中存一行记录,因此我们的数据库会出现大量冗余(也就是说不满足数据库第二范式)。因此,我们应该这样去设计数据库:
    在这里插入图片描述
    看到了吗?这里的“Record”是一个弱实体,它的主键是“学期主键+学生主键”,代表学生参加课程这一行为,抽象成为了弱实体。为什么要用学期表的主键和学生表的主键呢?因为一个学生、一个学期,那么就只能参加一门课程了,所以根据主键唯一标识每行记录的原则,应该这样去选取。课程表的主键成为了Record表的外键,课程表与Record表之间存在一对多关系。

    在这个例子中,学生、课程是业务需求描述中显而易见的实体,“期”也可以认为是比较明显的实体,但“参加”这个动词在我们的数据库中便成为了“参加记录” ,也就是Record实体。

    教务系统数据库设计(二)

    这一部分的业务需求是这样的:

    老师授课。

    似乎业务需求很简单,但事实上,多位老师可以独立上同一门课,也可以共同上同一门课。一位老师可以参与多门课的授课。真实的教务系统的确是这个样子的。一般,像马原、高数等课程是多位老师独立授课,专业核心课大多是多位老师共同为同一班级授课。那么数据库要怎样设计呢?
    在这里插入图片描述
    像这样吗?老师、课程之间建立多对多关系?不难发现,这样的多对多联系无法区分上面所说的两种授课情况。也就是说,我们必须引入第三个表,才有可能实现业务需求,两张表格是行不通的。我是这样设计的:
    在这里插入图片描述
    在课程表与老师表之间,引入了新的一张表格——排课表。一个课程可以安排多次排课,一个排课就对应一个独立的授课安排,可以由一位老师完成,也可以由多位老师完成。那么像马原授课这种多位老师独立授课的情况该如何解决呢?在排课表中,认为不同老师的马原课是同一课程(引用Course表中同一记录的主键作为外键),但是它们是不同的排课(ArangeNo不同,可能一个是1,另一个是2)。也正因如此,排课表的主键是组合主键(课程编号+排课编号,如CS163、1)。

    这个例子中,需求中并没有提“排课”这一实体,这个实体完全是我们为了满足需求而定义的,甚至它和课程表在概念上还有点关系。注意到了吗,这里的“关系”就是弱实体概念中所说的“依赖”!

    四、 对强实体与弱实体的总结

    1. 区别弱实体与强实体的关键在于主键,“依赖”的实质是主键之间的关系。所以归根到底,就一个主键之间是否有关系、主键是否是组合主键的问题。

    2. 弱实体与强实体可以相互转换,没有绝对意义上的强与弱。既然区别弱实体与强实体的关键在于主键,那么一个同样意义的表,当我给它一个编号作为主键,那么它就不是弱实体,而如果我令它的主键是组合主键,它就是弱实体。就像刚刚,我们说排课表的主键是组合主键(课程编号+排课编号,如CS163、1),所以它是弱实体,那么如果我定义排课编号是“CS16301”,而不再是“1”,那么它的主键(排课编号)就不再需要课程编号,它就成为了强实体。

    3. 弱实体也可以依赖于弱实体。就像第一个例子中的Session,它依赖于Day,Day就是一个弱实体。

    4. 弱实体与它所依赖的实体之间的关系只能是1:1或n:1。也就是说,一个弱实体实例不可能依赖于同一实体的多个实例。这个其实很好理解,因为如果弱实体实例A依赖于实例B,那么A的主键要包括B的主键,所以A当然不可以依赖于很多个B。

    5. 业务需求决定弱实体的定义,分三种情况:

      情况一、 业务需求中明确的弱实体
      情况二、 业务需求中隐含的弱实体
      情况三、 业务需求中无、但为实现业务需求不得不定义的弱实体

      如果觉得这篇文章对你有帮助,请给博主点个赞!

    展开全文
  • 知识图谱实体定义

    千次阅读 2020-07-18 22:56:25
    前一篇博文《Neo4j构建目标知识图谱》提到知识图谱的构建中实体及关系的定义是个难点,本篇试图总结经验。 2.知识图谱是什么 知识图谱本质上是一种语义网络,用图的形式描述客观事物,这里的图指的是数据...

    1.引言

    在前一篇博文《Neo4j构建目标知识图谱》中提到知识图谱的构建中实体及关系的定义是个难点,在本篇中试图总结经验。

    2.知识图谱是什么

    知识图谱本质上是一种语义网络,用图的形式描述客观事物,这里的图指的是数据结构中的图,也就是由节点和边组成的,这也是知识图谱(Knowledge Graph)的真实含义。知识图谱中的节点表示概念和实体,概念是抽象出来的事物,实体是具体的事物;边表示事物的关系和属性,事物的内部特征用属性来表示,外部联系用关系来表示。很多时候,人们简化了对知识图谱的描述,将实体和概念统称为实体,将关系和属性统称为关系,这样就可以说知识图谱就是描述实体以及实体之间的关系。实体可以是人,地方,组织机构,概念等等,关系的种类更多,可以是人与人之间的关系,人与组织之间的关系,概念与某个物体之间的关系等等,以下是一个例子。
    在这里插入图片描述
    例如上图展示的是毛选中的基本信息知识图谱,节点的信息分别为:作者、书名、主要问题(三大问题)、每本书中的主要内容观点抽象化。边的信息主要为:依据、属性特点等。

    3.知识图谱是怎么组织数据的

    知识图谱是由实体和实体的关系组成,通过图的形式表现出来,那么实体和实体关系的这些数据在知识图谱中怎么组织呢,这就涉及到三元组的概念,在知识图谱中,节点-边-节点可以看作一条记录,第一个节点看作主语,边看作谓语,第二个节点看作宾语,主谓宾构成一条记录。比如曹操的儿子是曹丕,曹操是主语,儿子是谓语,曹丕是宾语。再比如,曹操的小名是阿瞒,主语是曹操,谓语是小名,宾语是阿瞒。知识图谱就是由这样的一条条三元组构成,围绕着一个主语,可以有很多的关系呈现,随着知识的不断积累,最终会形成一个庞大的知识图谱,知识图谱建设完成后,会包含海量的数据,内涵丰富的知识。以上基础知识来源于[知识图谱基础知识之一——人人都能理解的知识图谱]

    4.知识图谱构建的基本模式

    知识图谱中实体和关系的定义通常是基于需求导向的,例如,我们想构建一个体现导师、学生人物关系的知识图谱时,那么我们可以定义(导师->指导->学生)这样的三元组;再者,当我们想构建体现学校、导师、学生关系时,我们可以定义为(导师->属于->学校;导师->指导->学生)。

    在学术上,知识图谱模式层的定义往往需要领域专家的参与,而且模式层实体和关系的定义是需要迭代进行的。例如,当我们想构建一个生物医疗知识图谱时往往很难,因为这里涉及大量的医学名词,非医学专业的对这些名词的理解很困难,更别谈充分理解融会贯通后定义了。但是领域知识图谱的定义往往更加重要,也是科研中的主要研究方向。

    通常,知识图谱的构建分为两个关键步骤:1、模式层定义:实体定义、实体关系定义;2、实体及关系抽取。

    而模式层定义中的两步:实体定义、实体关系定义也有一些基本的思路。

    实体定义:
    实体定义中有两种思路,一种是自顶向下,一种是自底向上。所谓的自顶向下即先确定目标需求,再制定实体的关键概念。例如,我们想探索一下基因和蛋白质的关系,那么我们就制定实体基因和蛋白质,并且可以制定关系"促进"、“抑制”;再如想了解基因和疾病的关系,那么我们指定实体为"基因"、“疾病”,关系为"正向作用"、“负向作用”。总归而言,在这个模式中我们是有目标导向的,我们根据目标需求来制定相应的实体关系。例如我们想了解公司股票、人物的结构关系,那么我们可以制定如下的模式层:
    在这里插入图片描述
    在自顶向下的模式中通常基于领域专家的判断,制定较为专业的模式。

    另一种模式是自底向上,这个策略是一种无奈之举,毕竟自顶向下往往借助领域专家的经验,这个过程限制条件太多,模式的定义周期太长很耗时间。那么这个时候就得从底层,也就是数据层找思路,我们的可用数据是什么。例如当我们想制定一个金融知识图谱时,我们能拿到的公开数据是新闻媒体财经频道的文本,这时候我们对文本的数据进行总结,发现有些词汇还是比较集中的,例如公司、股票、指数、基金。关系有:上涨、下跌、跌停等。又如我们只有军事报道文本时,我们可以发现这类文本中的核心词汇为:中国、美国等国别地区;武器装备(又可分海陆空三军装备);军事头衔等。

    这个模式也是一种迭代的过程,在实践中需要不断地调整,通常的做法是先抽样一批数据来标注,然后调整模式定义,之后再确定一个较为合理的模式进行后续图谱构建。

    整体而言,不管是自顶向下还是自底向下,我们都很难一次做到很完美,比较好的思路是上述抽样定义再修改的过程。如果能有现成的或者目标明确的定义那就最好,如果没有的话可以先定义简单的实体关系,然后一步一步扩展实体并修改,反复几次之后就能制定一个较为合理的模式。

    展开全文
  • 需求分析系统参与者的概念和确定        参与者是与软件系统进行交互的外部实体,它不属于软件系统,可以是使用系统的用户,也可以是与系统进行交互的其它系统或硬件设备。常见的系统参与者有三类:...

    需求分析中系统参与者的概念和确定

     

     

     

        参与者是与软件系统进行交互的外部实体,它不属于软件系统,可以是使用系统的用户,也可以是与系统进行交互的其它系统或硬件设备。常见的系统参与者有三类:用户、外部系统、系统的定时任务。在面对一个较大软件系统时,要确定参与者并不容易,可通过用户回答下列一些问题的答案来识别参与者:

     

        ①谁使用系统的主要功能?

     

        ②谁从系统获取信息?谁向系统提供信息?

     

        ③谁管理系统?谁支持、维护系统?

     

        ④谁对系统产生的结果感兴趣?

     

        ⑤系统需要操纵哪些硬件?

     

        ⑥系统需要与哪些其它系统交互(包含其它计算机系统和其它应用程序)?

     

        确定可能使用该产品的各种用户类,并描述他们的相关特征。描述各类各级用户的访问模式,如通过内联网访问或通过网间互联平台访问等,建议增加图示。

     

        描述用户管理模式--(即用户与用户之间的管理关系)。

    展开全文
  • 之前写过一篇关于需求分析描述细节需要注意的规则和约束,今天看徐峰的软件最佳实践时,看到了更为总结的描述,下面摘录进来: 规则是实现时应该考虑的东西,约束是对技术手段选择起到限制作用的各种条件。 ...
  • 阅读综述性论文是一种能够快速了解某一领域的方法,接下来通过今年的一篇...电子病历的文本内容是医务人员按照《病历书写基本规范》和《电子病历基本规范(试行)》相关书写规定,围绕患者医疗需求与服务活动而记录
  • 前面的课程,我们了解了什么是事件?事件是可以描述的、值得记录的某一特定时间和地点发生的事情,当事件发生时,系统要做出响应。系统可能会响应外部发生的事件,也可能会响应系统内部发生的事件,也可能...
  • 第二章 需求确定

    千次阅读 2019-01-16 16:15:00
    功能性需求还可以进一步分为功能性需求和数据需求 文档模板 项目准备、 项目的目的和范围 业务环境 利益相关者stackholders 多种解决方案 文档综述 系统服务(功能需求)——占总篇幅...
  • 拿着用户编写的原始需求,编写我们自己的需求规格说明书,之所以重要,就在于用户编写的原始需求,是脱离了技术实现,编写的一份十分理想的业务需求。理想与现实总是有差距,我们之所以要编写自己的需求规格说明书,...
  • eclipse反向生成hibernate实体类+jpa注释
  • 【命名实体识别(NER)】(1):命名实体识别综述

    万次阅读 多人点赞 2019-03-23 09:41:44
    命名实体识别综述 什么是命名实体识别? 命名实体识别(Named Entity Recognition,简称NER),又称作**“专名识别”,是自然语言处理的一项基础...确定实体的类型(人名、地名、机构名或其他) NER系统就是从...
  • 拿着用户编写的原始需求,编写我们自己的需求规格说明书,之所以重要,就在于用户编写的原始需求,是脱离了技术实现,编写的一份十分理想的业务需求。理想与现实总是有差距,我们之所以要编写自己的需求规格说明书,...
  • 实体关系抽取综述

    万次阅读 2018-06-11 16:14:01
    实体关系抽取作为信息抽取领域的重要研究课题,其主要目的是抽取句子已标记实体对之间的语义关系,即在实体识别的基础上确定无结构文本中实体对间的关系类别,并形成结构化的数据以便存储和取用。 从用户需求层面...
  • CSDN发表文章可以复制截图,保存却...但是最近有点洁癖,不想引用太多外来组件,所以尝试着使用了传说的“EF”(尽管之前使用的devart已经是对EF的使用了,但我这人比较懒,不习惯了解太深入的东西,知道怎么用就行
  • 命名实体识别——日期识别

    千次阅读 2018-07-26 15:36:32
    其目的是识别语料的人名、地名、组织结构名等命名实体,由于这些命名实体在不断地更新,很难词典全部列出,所以就对这些词的识别词汇形态处理任务单独处理,也就是NER技术。 而命名实体识别效果的评判...
  • 需求工程规格说明、需求验证、需求管理

    千次阅读 多人点赞 2020-04-24 18:52:14
    需求工程的面谈和原型(8、9章) 需求获取方法之观察与文档审查(10章) 第十一章 需求规格说明 需求获取:目标是得到用户需求——收集需求信息 需求分析:目标是更深刻的理解用户需求——界定能够让用户满意的...
  • 需求分析的问题总结

    千次阅读 2014-06-29 10:41:07
    阅读完林锐《软件工程与项目管理解析》关于需求分析
  • 实体-属性

    2016-04-19 10:36:00
    书体形成表,如"用户"就是一个实体,属性则为表的列(字段),如对应实体"用户"属性包含"用户名"、"用户ID"等等。 程序需求说明: 1、项目描述、目标?(初步完成,待定修改) 2、画一个功能模块图?(功能...
  • 拿着用户编写的原始需求,编写我们自己的需求规格说明书,之所以重要,就在于用户编写的原始需求,是脱离了技术实现,编写的一份十分理想的业务需求。理想与现实总是有差距,我们之所以要编写自己的需求规格说明书,...
  • 需求工程之需求跟踪

    2020-04-23 09:35:25
    目录需求跟踪需求跟踪的主要意义需求跟踪的主要目标需求跟踪分为:需求跟踪好处:需求跟踪能力链:跟踪能力联系链可能的信息源:需求跟踪的实现方法:需求跟踪矩阵优缺点:实体联系模型优缺点:交叉引用优缺点:需求...
  • UML边界类、控制类和实体

    万次阅读 2017-04-28 08:28:15
    实体类(Entity Class); (3). 控制类(Control Class); 边界类 (1).用来描述什么问题? 边界类用于描述外部参与者与系统之间的交互。 边界类是一种用于对系统外部环境与其内部运作之间的交互进行建模的类。...
  • 需求捕获的心理战

    千次阅读 2008-11-12 08:30:00
    《SERU需求过程框架系列文章之二》需求捕获的心理战 需求捕获的过程是和人打交道的过程,而只要是和人打交道就一定会遇到各种心理现象,而有些负面、消极的心理现象必将对需求捕获造成巨大的障碍。笔者自己的...
  • 实体解析 (EntityResolution) 实体解析(ER)是一种用于判断两条记录是否指向同一事物的过程。实体这个术语描述了过程的目标是真实世界的事物,比如某个人,地点或者物品。 而解析则描述了回答这样的一个问题的...
  • 而且,一些项目管理顾问的PPT课件,以及一些软件项目管理的技术图书和教程,也把“需求变更”作为单独的一项来研究。本文,与您共同探讨软件开发项目需求变更发生的原因、需求变更控制,以及当发生需求...
  • 来自:python遇见NLP 阅读综述性论文是一种能够快速了解某一领域的方法,接下来通过今年的一篇综述性论文来了解一下近五年来中文电子病历的命名实体识别研究进展。基本的,我...
  • 确定对系统的综合要求 1. 功能需求 这方面的需求指定系统必须提供的服务。通过需求分析应该划分出系统必须完成的所有功能。 2. 性能需求 性能需求指定系统必须满足的定时约束或容量约束,通常包括速度(响应时间...
  • C#之三十七 实体

    千次阅读 2016-05-31 20:48:36
    3.1 使用实体类构建三层结构概述 在上一章的三层架构,我们使用DataSet来进行数据的传递,但OOP的开发,有很大的局限性:1. DataSet不具备良好的面向对象特性,使用起来不够直观、方便。2. 对DataSet...
  • 但是怎样实际有效地使用UML使之发挥应有的作用,怎样捕捉用户心中的需求并转换成明确的UML图形,怎样把自己心中的设计意图通过UML图形准确地表达出来,以及各职责人员如何通过UML图形进行有效沟通,关于这些,却...
  • 命名实体识别以及词性自动标注

    千次阅读 2018-07-09 12:04:26
    一、命名实体识别大数据风靡的今天,不从里面挖出点有用的信息都不好意思见人,人工智能号称跨过奇点,统霸世界,从一句话里都识别不出一个命名实体?不会的,让我们大话自然语言处理的囊中取物,看看怎么样能让...
  • 实体-联系模型

    2020-12-20 22:08:32
    实体-联系(Entity-Relationship, E-R)模型(以下简称E-R模型)的提出旨在方便数据库的设计,它是通过允许定义代表数据全局...建模汇中,我们通常抽象地使用术语“实体集”,而不是指某个个别实体的特别集合。 实体

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,425
精华内容 41,370
关键字:

如何在需求中确定实体