我目前正在寻找约100 / 200k用户存储约350万张照片。我只在aws上使用mysql数据库。我的问题是关于存储照片参考的最有效方法。我只知道两种方式,我正在寻找专家意见。
选择A
一个带有photo_url列的用户表,在该列中我将构建一个逗号分隔的照片列表,它们都维护名称和排序顺序。业务逻辑将处理从照片名称中提取路径并附加照片大小。缺点是处理费用。
数据库示例
"0ea102, e435b9, etc"
业务逻辑将根据照片名称
构建以下网址/0e/a1/02.jpg
/0e/a1/02_thumb.jpg
/e4/35/b9.jpg
/e4/35/b9_thumb.jpg
选择B - 在用户表上连接的关系表,包含以下字段。我只是担心我可能会遇到潜在的数据库性能问题。
pk
user_id
photo_url_800
photo_url_150
photo_url_45
order
有没有人对更好的解决方案有任何建议?
答案 0 :(得分:2)
最好和最常见的答案是:选择B - 在用户表上加入关系表,并带有以下字段。
id
order
user_id
desc
photo_url_800
photo_url_150
photo_url_45
date_uploaded
或混合,其中,您单独存储文件名,并将照片目录添加到您的业务逻辑层。
我的分析,你的第一个选择是一个不好的做法。数据库不建议使用逗号分隔字段。您很难更新这些字段并在其上添加说明。
关于表格优化,您可能希望看到这些文章:
答案 1 :(得分:1)
以下是使用hibernate ORM,Christian Mark和我的混合解决方案的最终解决方案示例。
@Entity
public class Photo extends StatefulEntity {
private static final String FILE_EXTENSION_JPEG = ".jpg";
private static final String ROOT_PHOTO_URL = "/photo/";
private static final String PHOTO_SIZE_800 = "_800";
private static final String PHOTO_SIZE_150 = "_150";
private static final String PHOTO_SIZE_100 = "_100";
private static final String PHOTO_SIZE_50 = "_50";
@ManyToOne
@JoinColumn(name = "profile_id", nullable = false)
private Profile profile;
//Example "a1d2b0" which will later get parsed into "/photo/a1/d2/b0_size.jpg"
//using the generatePhotoUrl business logic below.
@Column(nullable = false, length = 6)
private String fileName;
private boolean temp;
@Column(nullable = false)
private int orderBy;
@Temporal(TemporalType.TIMESTAMP)
private Date dateUploaded;
public Profile getProfile() {
return profile;
}
public void setProfile(Profile profile) {
this.profile = profile;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Date getDateUploaded() {
return dateUploaded;
}
public void setDateUploaded(Date dateUploaded) {
this.dateUploaded = dateUploaded;
}
public boolean isTemp() {
return temp;
}
public void setTemp(boolean temp) {
this.temp = temp;
}
public int getOrderBy() {
return orderBy;
}
public void setOrderBy(int orderBy) {
this.orderBy = orderBy;
}
public String getPhotoSize800() {
return generatePhotoURL(PHOTO_SIZE_800);
}
public String getPhotoSize150() {
return generatePhotoURL(PHOTO_SIZE_150);
}
public String getPhotoSize100() {
return generatePhotoURL(PHOTO_SIZE_100);
}
public String getPhotoSize50() {
return generatePhotoURL(PHOTO_SIZE_50);
}
private String generatePhotoURL(String photoSize) {
String firstDir = getFileName().substring(0, 2);
String secondDir = getFileName().substring(2, 4);
String photoName = getFileName().substring(4, 6);
StringBuilder sb = new StringBuilder();
sb.append(ROOT_PHOTO_URL);
sb.append("/");
sb.append(firstDir);
sb.append("/");
sb.append(secondDir);
sb.append("/");
sb.append(photoName);
sb.append(photoSize);
sb.append(FILE_EXTENSION_JPEG);
return sb.toString();
}
}